home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 60750 / 60750.xpi / surfcanyon_sc.xpi / content / surfcanyon.js < prev    next >
Text File  |  2009-11-13  |  84KB  |  2,994 lines

  1. // 2009/11/13_22:36:38
  2. scIsFF = (navigator.userAgent.indexOf('Firefox') > 0);
  3. scIsIE = (navigator.userAgent.indexOf('MSIE') > 0);
  4. scIsIE6Or7 = (navigator.userAgent.indexOf('MSIE 6') > 0) || (navigator.userAgent.indexOf('MSIE 7') > 0);
  5. scIsIE8 = (navigator.userAgent.indexOf('MSIE 8') > 0);
  6. scIsSafariMac = ((navigator.userAgent.indexOf('Safari') > 0) && (navigator.userAgent.indexOf('Mac OS X') > 0));
  7.  
  8. scDoAnimatedRecs = false;
  9. scDisplayErrors = false;
  10. scNumCraigslistResultsPerPage = 20;
  11.  
  12. function initIE() {
  13.     var httpRequests = new VBArray(window.http_request).toArray();
  14.     var busyRequests = new Array(httpRequests.length);
  15.  
  16.     getFreeRequest = function() {
  17.         for (var i = 0; i < busyRequests.length; i++) {
  18.             if (!busyRequests[i]) {
  19.                 return i;
  20.             }
  21.         }
  22.         return 0;
  23.     }
  24.     
  25.     ajax = function(params) {
  26.         var requestNum = getFreeRequest();
  27.         busyRequests[requestNum] = true;
  28.         var httpRequest = httpRequests[requestNum];
  29.  
  30.         var requestWrapper = new Object();
  31.         requestWrapper.httpRequest = httpRequest;
  32.  
  33.         var url = params["url"];
  34.         requestWrapper.url = url;
  35.     
  36.         httpRequest.open(params["method"], url, true);
  37.     
  38.         var headers = params["headers"];
  39.         if (headers) {
  40.             for (var header in headers) {
  41.                 httpRequest.setRequestHeader(header, headers[header]);
  42.             }
  43.         }
  44.     
  45.         var onload = params["onload"];
  46.         var onerror = params["onerror"];
  47.         httpRequest.onreadystatechange = function() {
  48.             if (httpRequest.readyState == 4) { 
  49.                 busyRequests[requestNum] = false;
  50.                 if (httpRequest.status == 200) {
  51.                     if (onload) {
  52.                         onload(requestWrapper);
  53.                     }
  54.                 } else {
  55.                     if (onerror) {
  56.                         onerror(requestWrapper);
  57.                     }
  58.                 }
  59.             }
  60.         };
  61.         httpRequest.send(params["data"]);
  62.     }
  63.     
  64.     EventRecord = function(event) {
  65.         this.srcElement = event.srcElement;
  66.         this.shiftKey = event.shiftKey;
  67.         this.ctrlKey = event.ctrlKey;
  68.         this.metaKey = event.metaKey;
  69.         this.cancelBubble = true;
  70.         this.returnValue = false;
  71.     }
  72.  
  73.     onmouseup = function() {
  74.         clickHandler(window.event);
  75.     }
  76.  
  77.     log = function(msg, isError) {
  78.         if (scDisplayErrors && isError) {
  79.             alert(msg);
  80.         }
  81.     }
  82.  
  83.     getBoolPreferenceValue = function(name) {
  84.         return window.surfcanyonObject.GetPreference(name) == 1;
  85.     }
  86.     
  87.     setBoolPreferenceValue = function(name, value) {
  88.         window.surfcanyonObject.SetPreference(name, value ? 1 : 0);
  89.     }
  90.  
  91.     getCharPreferenceValue = function(name) {
  92.         return window.surfcanyonObject.GetPreference(name);
  93.     }
  94.     
  95.     setCharPreferenceValue = function(name, value) {
  96.         window.surfcanyonObject.SetPreference(name, value);
  97.     }
  98.  
  99.     openNewTab = function(url) {
  100.         window.open(url);
  101.     }
  102. }
  103.  
  104. function initSafariMac() {
  105.     ajax = function(params) {
  106.         var url = params.url;
  107.         var headers = params.headers;
  108.         var method = params.method;
  109.         var data = params.data;
  110.         var onload = params.onload;
  111.         var onerror = params.onerror;
  112.         var request;
  113.         
  114.         try {
  115.             request = surfcanyonObject.CreateRequest();
  116.             
  117.             var userVariables = params.vars;
  118.             if (userVariables) {
  119.                 for (var varName in userVariables) {
  120.                     request.SetVariable(userVariables[varName], varName);
  121.                 }
  122.             }
  123.             
  124.             var headers = params.headers;
  125.             if (headers) {
  126.                 for (var header in headers) {
  127.                     request.SetHeader(header, headers[header]);
  128.                 }
  129.             }
  130.             
  131.             request.SetOnLoadFunction(onload ? onload.toString() : null);
  132.             request.SetOnErrorFunction(onerror ? onerror.toString() : null);
  133.             request.SendRequest(url, method, data, true);
  134.         }
  135.         catch (e) {
  136.             log(e);
  137.         }
  138.     
  139.     }
  140.  
  141.     log = function(msg, isError) {
  142.         window.console.log(msg);
  143.     }
  144.     
  145.     getBoolPreferenceValue = function(name) {
  146.         return window.surfcanyonObject.GetPreference(name) == 1;
  147.     }
  148.     
  149.     setBoolPreferenceValue = function(name, value) {
  150.         window.surfcanyonObject.SetPreference(name, value ? 1 : 0);
  151.     }
  152.     
  153.     getCharPreferenceValue = function(name) {
  154.         return window.surfcanyonObject.GetPreference(name);
  155.     }
  156.     
  157.     setCharPreferenceValue = function(name, value) {
  158.         window.surfcanyonObject.SetPreference(name, value);
  159.     }
  160. }
  161.  
  162. function cancelEvent(event) {
  163.     if (event.cancelBubble) {
  164.         event.cancelBubble = true;
  165.     }
  166.     if (event.returnValue) {
  167.         event.returnValue = false;
  168.     }
  169.     if (event.stopPropagation) {
  170.         event.stopPropagation();
  171.     }
  172.     if (event.preventDefault) {
  173.         event.preventDefault();
  174.     }
  175. }
  176.  
  177. function getResponseText(xhr) {
  178.     return scIsIE ? xhr.httpRequest.responseText : xhr.responseText;
  179. }
  180.  
  181. function getText(s) {
  182.     return (s ? (scIsIE ? s.text : s.textContent) : '');
  183. }
  184.  
  185. function xmlParser(text) {
  186.     if (scIsIE) {
  187.         var xmlRoot = new ActiveXObject("Microsoft.XMLDOM");
  188.         xmlRoot.async = "false";
  189.         xmlRoot.loadXML(text);
  190.         return xmlRoot;
  191.     } else {
  192.         return (new DOMParser()).parseFromString(text, "text/xml");
  193.     }
  194. }
  195.  
  196. scGetDocument = function() {
  197.     return scIsFF ? content.document : document;
  198. };
  199.  
  200. function getElementsByTagAndAttribute(tag, attrName, attrVal) {
  201.     var elements = scGetDocument().getElementsByTagName(tag);
  202.     var arr = [];
  203.     for (i = 0; i < elements.length; i++) {
  204.         var element = elements[i];
  205.         if (element.getAttribute(attrName) == attrVal) {
  206.             arr[arr.length] = element;
  207.         }
  208.     }
  209.     return arr;
  210. }
  211.  
  212. function getElementsByTagAndClass(tag, className) {
  213.     var elements = scGetDocument().getElementsByTagName(tag);
  214.     var arr = [];
  215.     for (i = 0; i < elements.length; i++) {
  216.         var element = elements[i];
  217.         if ((element.getAttribute('class') == className) || (element.getAttribute('className') == className)) {
  218.             arr[arr.length] = element;
  219.         }
  220.     }
  221.     return arr;
  222. }
  223.  
  224. function getImmediateChildren(node, tagName) {
  225.     var arr = [];
  226.     if (node && node.childNodes) {
  227.         var childNodes = node.childNodes;
  228.         for (var i = 0; i < childNodes.length; i++) {
  229.             var child = childNodes.item(i);
  230.             if (child.tagName && child.tagName.toUpperCase() == tagName.toUpperCase()) {
  231.                 arr[arr.length] = child;
  232.             }
  233.         }
  234.     }
  235.     return arr;
  236. }
  237.  
  238. function getChildren(node, tagName) {
  239.     var arr = [];
  240.     if (node && node.childNodes) {
  241.         var childNodes = node.childNodes;
  242.         for (var i = 0; i < childNodes.length; i++) {
  243.             var child = childNodes.item(i);
  244.             if (child.tagName && (!tagName || (child.tagName.toUpperCase() == tagName.toUpperCase()))) {
  245.                 arr[arr.length] = child;
  246.             }
  247.             if (child.hasChildNodes()) {
  248.                 arr = arr.concat(getChildren(child, tagName));
  249.             }
  250.         }
  251.     }
  252.     return arr;
  253. }
  254.  
  255. function getChildrenByTagThatHaveAttribute(node, tagName, attrName) {
  256.     var children = getChildren(node, tagName);
  257.     var arr = [];
  258.     for (i = 0; i < children.length; i++) {
  259.         var child = children[i];
  260.         if (child.getAttribute(attrName)) {
  261.             arr[arr.length] = child;
  262.         }
  263.     }
  264.     return arr;
  265. }
  266.  
  267. function getChildrenByTagAndAttribute(node, tagName, attrName, attrVal) {
  268.     var children = getChildren(node, tagName);
  269.     var arr = [];
  270.     for (i = 0; i < children.length; i++) {
  271.         var child = children[i];
  272.         if (child.getAttribute(attrName) == attrVal) {
  273.             arr[arr.length] = child;
  274.         }
  275.     }
  276.     return arr;
  277. }
  278.  
  279. function getChildrenByTagAndClass(node, tagName, attrVal) {
  280.     var children = getChildren(node, tagName);
  281.     var arr = [];
  282.     for (i = 0; i < children.length; i++) {
  283.         var child = children[i];
  284.         if ((child.getAttribute('class') == attrVal) || (child.getAttribute('className') == attrVal)) {
  285.             arr[arr.length] = child;
  286.         }
  287.     }
  288.     return arr;
  289. }
  290.  
  291. function classWord() {
  292.     return scIsIE6Or7 ? 'className' : 'class';
  293. }
  294.  
  295. function getMessage(msgCode) {
  296.     var lang = getLang(scCurrentPageDomain);
  297.     if (lang == 'de') {
  298.         var uUmlaut = String.fromCharCode(252);
  299.         switch (msgCode) {
  300.             case 'MORE_RESULTS':
  301.                 return "Mehr Ergebnisse >>";
  302.             case 'RESET_RECS':
  303.                 return "Empfehlungen zur" + uUmlaut + "cksetzen";
  304.             case 'NO_RECS':
  305.                 return "F" + uUmlaut + "r diese Anfrage stehen keine Empfehlungen von Surf Canyon zur Verf" + uUmlaut + "gung";
  306.             case 'GOOGLE_AD_HEADER':
  307.                 return "von Surf Canyon empfohlene gesponserte Links";
  308.             case 'YAHOO_AD_HEADER':
  309.                 return "von Surf Canyon empfohlene gesponserte Ergebnisse";
  310.         }
  311.     } else if (lang == 'fr') {
  312.         var aAccent = String.fromCharCode(224);
  313.         var eAccent = String.fromCharCode(233);
  314.         var eHat = String.fromCharCode(234);
  315.         switch (msgCode) {
  316.             case 'MORE_RESULTS':
  317.                 return "R" + eAccent + "sultats suivants >>";
  318.             case 'RESET_RECS':
  319.                 return "Effacez les r" + eAccent + "sultats sugg" + eAccent + "r" + eAccent + "s";
  320.             case 'NO_RECS':
  321.                 return "Surf Canyon n'a pas de r" + eAccent + "sultat " + aAccent + " sugg" + eAccent + "rer pour cette requ" + eHat + "te.";
  322.             case 'GOOGLE_AD_HEADER':
  323.                 return "Lien commerciaux sugg" + eAccent + "r" + eAccent + "s par Surf Canyon";
  324.             case 'YAHOO_AD_HEADER':
  325.                 return "Lien sponsoris" + eAccent + "s sugg" + eAccent + "r" + eAccent + "s par Surf Canyon";
  326.         }
  327.     } else if (lang == 'es') {
  328.         var aAccent = String.fromCharCode(225);
  329.         var uAccent = String.fromCharCode(250);
  330.         switch (msgCode) {
  331.             case 'MORE_RESULTS':
  332.                 return "M" + aAccent + "s resultados >>";
  333.             case 'RESET_RECS':
  334.                 return "Borrar recomendaciones";
  335.             case 'NO_RECS':
  336.                 return "Surf Canyon no tiene recomendaciones para su b" + uAccent + "squeda.";
  337.             case 'GOOGLE_AD_HEADER':
  338.                 return "Enlaces patrocinados recomendados por Surf Canyon";
  339.             case 'YAHOO_AD_HEADER':
  340.                 return "Enlaces patrocinados recomendados por Surf Canyon";
  341.         }
  342.     } else if (lang == 'pt') {
  343.         var aTilde = String.fromCharCode(227);
  344.         var cCedilla = String.fromCharCode(231);
  345.         var oTilde = String.fromCharCode(245);
  346.         switch (msgCode) {
  347.             case 'MORE_RESULTS':
  348.                 return "Mais resultados >>";
  349.             case 'RESET_RECS':
  350.                 return "Zerar recomenda" + cCedilla + oTilde + " es";
  351.             case 'NO_RECS':
  352.                 return "N" + aTilde + "o existem recomenda" + cCedilla + oTilde + "es da Surf Canyon para essa consulta.";
  353.             case 'GOOGLE_AD_HEADER':
  354.                 return "Surf Canyon Recomendou os Links Patrocinados";
  355.             case 'YAHOO_AD_HEADER':
  356.                 return "SURF CANYON RECOMMENDOU OS LINKS PATROCINADOS";
  357.         }
  358.     } else if (lang == 'ru') {
  359.         switch (msgCode) {
  360.             case 'MORE_RESULTS':
  361.                 return '\u0415\u0449\u0451 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044B >>';
  362.             case 'RESET_RECS':
  363.                 return '\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438';
  364.             case 'NO_RECS':
  365.                 return '\u041f\u043e \u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e';
  366.             case 'GOOGLE_AD_HEADER':
  367.             case 'YAHOO_AD_HEADER':
  368.         }
  369.     } else {
  370.         switch (msgCode) {
  371.             case 'MORE_RESULTS':
  372.                 return "More Results >>";
  373.             case 'RESET_RECS':
  374.                 return "Reset recommendations";
  375.             case 'NO_RECS':
  376.                 return "There are no Surf Canyon recommendations available for this query.";
  377.             case 'GOOGLE_AD_HEADER':
  378.                 return "Surf Canyon Recommended Sponsored Links";
  379.             case 'YAHOO_AD_HEADER':
  380.                 return "SURF CANYON RECOMMENDED SPONSOR RESULTS";
  381.         }
  382.     }
  383.  
  384.     if (msgCode == 'RECS_NOTIFICATION') {
  385.         return 'Surf Canyon has added recommended search results to this search page. These were personally calculated for you "on-the-fly" based on the search results that you selected.';
  386.     }
  387.  
  388.     if (msgCode == 'PAGE_NOTIFICATION') {
  389.         return 'Surf Canyon has customized the next page of search results. These were calculated "on-the-fly" based on the search results that you have selected or skipped over.';
  390.     }
  391. }
  392.     
  393. function startsWith(text, substring) {
  394.     return text && substring && (text.indexOf(substring) == 0);
  395. }
  396.  
  397. function endsWith(text, substring) {
  398.     var b = false;
  399.     if (text && substring) {
  400.         var pos = text.lastIndexOf(substring);
  401.         b = (pos != -1) && (pos == (text.length - substring.length));
  402.     }
  403.     return b;
  404. }
  405.  
  406. function contains(text, substring) {
  407.     return text && substring && (text.indexOf(substring) >= 0);
  408. }
  409.  
  410. function isPartner(partnerCode) {
  411.     return partnerCode && (partnerCode.toUpperCase() != 'SC') && (partnerCode.toUpperCase() != 'MZ') && (partnerCode.toUpperCase() != 'IEG');
  412. }
  413.  
  414. function getDomainName(url) {
  415.     if (startsWith(url, "http://")) {
  416.         url = url.substring(7);
  417.     } else if (startsWith(url, "https://")) {
  418.         url = url.substring(8);
  419.     } else if (startsWith(url, "ftp://")) {
  420.         url = url.substring(6);
  421.     }
  422.  
  423.     if (startsWith(url, "www.")) {
  424.         url = url.substring(4);
  425.     }
  426.  
  427.     var slashPos = url.indexOf('/');
  428.     return (slashPos != -1) ? url.substring(0, slashPos) : url;
  429. }
  430.  
  431. function equalsOrIsSubdomainOf(subdomain, domain) {
  432.     if (subdomain == domain) {
  433.         return true;
  434.     }
  435.  
  436.     var domainLength = domain.length;
  437.     var subdomainLength = subdomain.length;
  438.     if ((subdomainLength <= domainLength) || !endsWith(subdomain, domain)) {
  439.         return false;
  440.     }
  441.  
  442.     var c = subdomain.charAt(subdomainLength - domainLength - 1);
  443.     return (c == '.');
  444. }
  445.  
  446. function isLexisWeb() {
  447.     var isLexisWeb = false;
  448.     try {
  449.         isLexisWeb = window && window.location && window.location.host && contains(window.location.host, 'lexisweb.com');
  450.     } catch (e) {
  451.     }
  452.     return isLexisWeb;
  453. }
  454.  
  455. function bigRandom() {
  456.     var r1 = ('' + Math.random()).substring(2);
  457.     var r2 = ('' + Math.random()).substring(2);
  458.     return r1 + r2;
  459. }
  460.  
  461. function getAllDisabled() {
  462.     return getBoolPreferenceValue('disabled');
  463. }
  464.  
  465. function setAllDisabled(val) {
  466.     var oldValue = getAllDisabled() ? 1 : 0;
  467.     var newValue = val ? 1 : 0;
  468.     var changed = (newValue != oldValue);
  469.  
  470.     // updateDisabledStatusInUI() reloads page, so only call it when necessary
  471.     if (changed) {
  472.         setBoolPreferenceValue("disabled", val);
  473.         updateDisabledStatusInUI(val, 'x');
  474.     }
  475. }
  476.  
  477. function getStatusBarIconDisabled() {
  478.     return getBoolPreferenceValue('status_bar_icon_disabled');
  479. }
  480.  
  481. function setStatusBarIconDisabled(val) {
  482.     var oldValue = getStatusBarIconDisabled() ? 1 : 0;
  483.     var newValue = val ? 1 : 0;
  484.     var changed = (newValue != oldValue);
  485.  
  486.     // updateDisabledStatusInUI() reloads page, so only call it when necessary
  487.     if (changed) {
  488.         setBoolPreferenceValue("status_bar_icon_disabled", val);
  489.         updateDisabledStatusInUI('x', val);
  490.     }
  491. }
  492.  
  493. function getUrlBarIconDisabled() {
  494.     return getBoolPreferenceValue('url_bar_icon_disabled');
  495. }
  496.  
  497. function setUrlBarIconDisabled(val) {
  498.     var oldValue = getUrlBarIconDisabled() ? 1 : 0;
  499.     var newValue = val ? 1 : 0;
  500.     var changed = (newValue != oldValue);
  501.  
  502.     if (changed) {
  503.         setBoolPreferenceValue("url_bar_icon_disabled", val);
  504.         reload();
  505.     }
  506. }
  507.  
  508. function getAffectGoogle() {
  509.     return getBoolPreferenceValue("enable_google");
  510. }
  511.  
  512. function setAffectGoogle(val) {
  513.     setBoolPreferenceValue("enable_google", val);
  514. }
  515.  
  516. function getAffectYahoo() {
  517.     return getBoolPreferenceValue("enable_yahoo");
  518. }
  519.  
  520. function setAffectYahoo(val) {
  521.     setBoolPreferenceValue("enable_yahoo", val);
  522. }
  523.  
  524. function getAffectBing() {
  525.     return getBoolPreferenceValue("enable_msn");
  526. }
  527.  
  528. function setAffectBing(val) {
  529.     setBoolPreferenceValue("enable_msn", val);
  530. }
  531.  
  532. function getAffectCraigslist() {
  533.     return getBoolPreferenceValue("enable_craigslist");
  534. }
  535.  
  536. function setAffectCraigslist(val) {
  537.     setBoolPreferenceValue("enable_craigslist", val);
  538. }
  539.  
  540. function getAffectLexis() {
  541.     return getBoolPreferenceValue("enable_lexis");
  542. }
  543.  
  544. function setAffectLexis(val) {
  545.     setBoolPreferenceValue("enable_lexis", val);
  546. }
  547.  
  548. function getShowRecsOnSRClick() {
  549.     return getBoolPreferenceValue("get_recs_on_sr_click");
  550. }
  551.  
  552. function setShowRecsOnSRClick(val) {
  553.     setBoolPreferenceValue("get_recs_on_sr_click", val);
  554. }
  555.  
  556. function getShowBullseyes() {
  557.     return getBoolPreferenceValue("show_bullseyes");
  558. }
  559.  
  560. function setShowBullseyes(val) {
  561.     setBoolPreferenceValue("show_bullseyes", val);
  562. }
  563.  
  564. function getAdStatus() {
  565.     return getCharPreferenceValue("ad_status");
  566. }
  567.  
  568. function setAdStatus(val) {
  569.     setCharPreferenceValue("ad_status", val);
  570. }
  571.  
  572. function getMaxNumRecsForSRSelection() {
  573.     return getCharPreferenceValue("max_num_recs");
  574. }
  575.  
  576. function setMaxNumRecsForSRSelection(val) {
  577.     setCharPreferenceValue("max_num_recs", val);
  578. }
  579.  
  580. function getAddedToSearchBar() {
  581.     return getBoolPreferenceValue("added_to_searchbar");
  582. }
  583.  
  584. function setAddedToSearchBar(val) {
  585.     setBoolPreferenceValue("added_to_searchbar", val);
  586. }
  587.  
  588. function getAddCLImagePreviews() {
  589.     return getBoolPreferenceValue("add_craigslist_images");
  590. }
  591.  
  592. function setAddCLImagePreviews(val) {
  593.     setBoolPreferenceValue("add_craigslist_images", val);
  594. }
  595.  
  596. function justDoingCraigslistImages() {
  597.     return (scSearchEngine == 'craigslist') && !getAffectCraigslist() && getAddCLImagePreviews();
  598. }
  599.  
  600. function getAddImagePreviews() {
  601.     var addPreviews = false;
  602.  
  603.     if (scIsFF && (scSearchEngine == 'google' || scSearchEngine == 'yahoo')) {
  604.         addPreviews = isGooglePreviewOn();
  605.     } else if (scSearchEngine == 'craigslist') {
  606.         addPreviews = getAddCLImagePreviews();
  607.     }
  608.  
  609.     return addPreviews;
  610. }
  611.  
  612. function getInstId() {
  613.     return getCharPreferenceValue("inst_id");
  614. }
  615.  
  616. function setInstId(value) {
  617.     setCharPreferenceValue("inst_id", value);
  618. }
  619.  
  620. function getPartnerCode() {
  621.     return getCharPreferenceValue("partner_code");
  622. }
  623.  
  624. function setPartnerCode(value) {
  625.     setCharPreferenceValue("partner_code", value);
  626. }
  627.  
  628. function getSubPartnerCode() {
  629.     return getCharPreferenceValue("sub_partner_code");
  630. }
  631.  
  632. function setSubPartnerCode(value) {
  633.     setCharPreferenceValue("sub_partner_code", value);
  634. }
  635.  
  636. function getInstTimestamp() {
  637.     return getCharPreferenceValue("inst_timestamp");
  638. }
  639.  
  640. function setInstTimestamp(value) {
  641.     setCharPreferenceValue("inst_timestamp", value);
  642. }
  643.  
  644. function getLastSeenSplash() {
  645.     return getCharPreferenceValue("last_seen_splash");
  646. }
  647.  
  648. function setLastSeenSplash(value) {
  649.     setCharPreferenceValue("last_seen_splash", value);
  650. }
  651.  
  652. function getFacebookUID() {
  653.     return getCharPreferenceValue("fb_uid");
  654. }
  655.  
  656. function setFacebookUID(value) {
  657.     setCharPreferenceValue("fb_uid", value);
  658. }
  659.  
  660. function getFacebookSessionKey() {
  661.     return getCharPreferenceValue("fb_session");
  662. }
  663.  
  664. function setFacebookSessionKey(value) {
  665.     setCharPreferenceValue("fb_session", value);
  666. }
  667.  
  668. function getCheckedDomains() {
  669.     return getCharPreferenceValue("checked_domains");
  670. }
  671.  
  672. function setCheckedDomains(value) {
  673.     setCharPreferenceValue("checked_domains", value);
  674. }
  675.  
  676. function getPreferredDomains() {
  677.     return getCharPreferenceValue("preferred_domains");
  678. }
  679.  
  680. function setPreferredDomains(value) {
  681.     setCharPreferenceValue("preferred_domains", value);
  682. }
  683.  
  684. function getDislikedDomains() {
  685.     return getCharPreferenceValue("disliked_domains");
  686. }
  687.  
  688. function setDislikedDomains(value) {
  689.     setCharPreferenceValue("disliked_domains", value);
  690. }
  691.  
  692. function getHourlyCode() {
  693.     return getCharPreferenceValue("hourly_code");
  694. }
  695.  
  696. function setHourlyCode(value) {
  697.     setCharPreferenceValue("hourly_code", value);
  698. }
  699.  
  700. function getHourlyCode2() {
  701.     return getCharPreferenceValue("hourly_code2");
  702. }
  703.  
  704. function setHourlyCode2(value) {
  705.     setCharPreferenceValue("hourly_code2", value);
  706. }
  707.  
  708. function getHourlyCodeTimestamp() {
  709.     return getCharPreferenceValue("hourly_code_timestamp");
  710. }
  711.  
  712. function setHourlyCodeTimestamp(value) {
  713.     setCharPreferenceValue("hourly_code_timestamp", value);
  714. }
  715.  
  716. function getTopOfPageRefinementsDisabled() {
  717.     var b = false;
  718.  
  719.     try {
  720.         b = getBoolPreferenceValue("top_of_page_refinements_disabled");
  721.     } catch (e) {
  722.     }
  723.  
  724.     return b;
  725. }
  726.  
  727. function setTopOfPageRefinementsDisabled(val) {
  728.     setBoolPreferenceValue("top_of_page_refinements_disabled", val);
  729. }
  730.  
  731. function getOdometerDisabled() {
  732.     var b = false;
  733.  
  734.     try {
  735.         b = getBoolPreferenceValue("odometer_disabled");
  736.     } catch (e) {
  737.     }
  738.  
  739.     return b;
  740. }
  741.  
  742. function setOdometerDisabled(val) {
  743.     setBoolPreferenceValue("odometer_disabled", val);
  744. }
  745.  
  746. function getCharPrefAsNum(name) {
  747.     var num = 0;
  748.  
  749.     try {
  750.         num = getCharPreferenceValue(name);
  751.         if (typeof num != 'number') {
  752.             if (!num || (num.length == 0) || (num.charAt(0) < '0') || (num.charAt(0) > '9')) {
  753.                 num = 0;
  754.             }
  755.         }
  756.     } catch (e) {
  757.     }
  758.  
  759.     return num;
  760. }
  761.  
  762. function incrementPref(name) {
  763.     var num = 0;
  764.     try {
  765.         num = Number(getCharPrefAsNum(name));
  766.     } catch (e) {
  767.     }
  768.  
  769.     setCharPreferenceValue(name, num + 1);
  770. }
  771.  
  772. function clearPref(name) {
  773.     setCharPreferenceValue(name, 0);
  774. }
  775.  
  776. function getNumSearches() {
  777.     return getCharPrefAsNum("num_searches");
  778. }
  779.  
  780. function incNumSearches() {
  781.     if (!getOdometerDisabled()) {
  782.         incrementPref("num_searches");
  783.     }
  784. }
  785.  
  786. function clearNumSearches() {
  787.     clearPref("num_searches");
  788. }
  789.  
  790. function getNumResultsClicked() {
  791.     return getCharPrefAsNum("num_results_clicked");
  792. }
  793.  
  794. function incNumResultsClicked() {
  795.     if (!getOdometerDisabled()) {
  796.         incrementPref("num_results_clicked");
  797.     }
  798. }
  799.  
  800. function clearNumResultsClicked() {
  801.     clearPref("num_results_clicked");
  802. }
  803.  
  804. function getNumResultsClickedWhenRecsAvailable() {
  805.     return getCharPrefAsNum("num_results_clicked_when_recs_available");
  806. }
  807.  
  808. function incNumResultsClickedWhenRecsAvailable() {
  809.     if (!getOdometerDisabled()) {
  810.         incrementPref("num_results_clicked_when_recs_available");
  811.     }
  812. }
  813.  
  814. function clearNumResultsClickedWhenRecsAvailable() {
  815.     clearPref("num_results_clicked_when_recs_available");
  816. }
  817.  
  818. function getNumRecsClicked() {
  819.     return getCharPrefAsNum("num_recs_clicked");
  820. }
  821.  
  822. function incNumRecsClicked() {
  823.     if (!getOdometerDisabled()) {
  824.         incrementPref("num_recs_clicked");
  825.     }
  826. }
  827.  
  828. function clearNumRecsClicked() {
  829.     clearPref("num_recs_clicked");
  830. }
  831.  
  832. function getSearchBoost() {
  833.     var val = '-';
  834.  
  835.     var divisor = getNumResultsClickedWhenRecsAvailable();
  836.     if (divisor > 0) {
  837.         val = Math.round(getNumRecsClicked() / divisor * 100) + '%';
  838.     }
  839.  
  840.     return val;
  841. }
  842.  
  843. function addToCheckedDomains(newDomain) {
  844.     newDomain = newDomain.toUpperCase();
  845.     var checkedDomains = getCheckedDomains();
  846.     var domains = checkedDomains ? checkedDomains.split(',') : [];
  847.  
  848.     var alreadyThere = false;
  849.     if (domains && domains.length > 0) {
  850.         for (var i = 0; i < domains.length; i++) {
  851.             var domain = domains[i].toUpperCase();
  852.             if (domain == newDomain) {
  853.                 alreadyThere = true;
  854.             }
  855.         }
  856.     }
  857.  
  858.     if (!alreadyThere) {
  859.         domains.push(newDomain);
  860.         setCheckedDomains(domains.join(','));
  861.     }
  862. }
  863.  
  864. function isServerError(s) {
  865.     return s && startsWith(s, '<html><head><title>Apache Tomcat') && contains(s, '<body><h1>HTTP Status ');
  866. }
  867.  
  868. function capitalizeFirstLetter(s) {
  869.     return (s && (s.length > 1)) ? (s.substring(0, 1).toUpperCase() + s.substring(1)) : s;
  870. }
  871.  
  872. scMakeSearchTermsBold = function(s) {
  873.     if (scSearchString && s) {
  874.         var searchString = scSearchString.replace(/\+/g, ' ');
  875.         var arr = searchString.split(' ');
  876.         for (var i = 0; i < arr.length; i++) {
  877.             var word = arr[i];
  878.             s = scMakeWordBold(s, word);
  879.         }
  880.     }
  881.  
  882.     return s.replace(/<\/b> <b>/g, ' ');
  883. };
  884.  
  885. scMakeWordBold = function(s, word) {
  886.     var output = s;
  887.  
  888.     if (s && word) {
  889.         output = '';
  890.         var wordLen = word.length;
  891.         var wordLC = word.toLowerCase();
  892.         for (var i = 0; i < s.length; i++) {
  893.             var substring = s.substr(i, wordLen);
  894.             if (substring.toLowerCase() == wordLC) {
  895.                 output = output + '<b>' + substring + '</b>';
  896.                 i = i + wordLen - 1;
  897.             } else {
  898.                 output = output + s.charAt(i);
  899.             }
  900.         }
  901.     }
  902.  
  903.     return output;
  904. };
  905.  
  906. scTruncateAtSpace = function(s, pos) {
  907.     if (s && pos) {
  908.         var spacePos = s.indexOf(' ', pos);
  909.         if (spacePos >= pos) {
  910.             s = s.substring(0, spacePos) + "...";
  911.         }
  912.     }
  913.  
  914.     return s;
  915. };
  916.  
  917. function getLocaleCode() {
  918.     var localeCode;
  919.  
  920.     if (scSearchEngine == 'bing') {
  921.         var cookieParts = scGetDocument().cookie.split('; ');
  922.         for (var i = 0; i < cookieParts.length; i++) {
  923.             var cookiePart = cookieParts[i];
  924.             if (startsWith(cookiePart, '_FP=') && contains(cookiePart, 'mkt=')) {
  925.                 var pos = cookiePart.indexOf('mkt=');
  926.                 localeCode = cookiePart.substring(pos + 4, pos + 9);
  927.             }
  928.         }
  929.     }
  930.  
  931.     return localeCode;
  932. }
  933.  
  934. function getLang(domain) {
  935.     var lang;
  936.     var ct = null;
  937.  
  938.     var localeCode = getLocaleCode();
  939.     if (localeCode) {
  940.         lang = localeCode.substring(0, 2);
  941.         return lang;
  942.     }
  943.     
  944.     if (domain.length > 4) {
  945.         if (domain.charAt(2) == '.') {
  946.             ct = domain.substring(0, 2);
  947.         } else if (domain.charAt(domain.length - 3) == '.') {
  948.             ct = domain.substring(domain.length - 2);
  949.         }
  950.     }
  951.  
  952.     if (ct == 'mx' || ct == 'es' || ct == 'ar' || ct == 'cl' || ct == 'cr' || ct == 'pe' || ct == 'pr' || ct == 'uy' || ct == 'py' || ct == 'bo') {
  953.         lang = 'es';
  954.     } else if (ct == 'br' || ct == 'pt') {
  955.         lang = 'pt';
  956.     } else if (ct == 'de' || ct == 'at') {
  957.         lang = 'de';
  958.     } else if (ct == 'it' || ct == 'fr' || ct == 'nl' || ct == 'fi' || ct == 'no' || ct == 'ru' || ct == 'fi' || ct == 'hu' || ct == 'ro' || ct == 'tr') {
  959.         lang = ct;
  960.     } else if (ct == 'dk') {
  961.         lang = 'da';
  962.     } else if (ct == 'se') {
  963.         lang = 'sv';
  964.     } else {
  965.         lang = 'en';
  966.     }
  967.  
  968.     return lang;
  969. }
  970.  
  971. function decodeEntities(s) {
  972.     var textarea = scGetDocument().createElement("textarea");
  973.     textarea.innerHTML = s.replace(/</g, "<").replace(/>/g, ">");
  974.     return textarea.value;
  975. }
  976.  
  977. function removeChildren(element) {
  978.     if (element && element.hasChildNodes()) {
  979.         while (element.childNodes.length >= 1) {
  980.             element.removeChild(element.firstChild);
  981.         } 
  982.     }
  983. }
  984.  
  985. function removeSimpleHtmlTags(s, retainImageTags) {
  986.     var openImgTag = retainImageTags ? '<img' : null;
  987.     var closeImgTag = retainImageTags ? '</img' : null;
  988.  
  989.     if (s) {
  990.         var output = '';
  991.         var len = s.length;
  992.         var inTag = false;
  993.         for (var i = 0; i < len; i++) {
  994.             var c = s.charAt(i);
  995.  
  996.             if (!inTag && (c == '<') && (s.substr(i, 4) != openImgTag) && (s.substr(i, 5) != closeImgTag)) {
  997.                 inTag = true;
  998.             } else if (inTag && (c == '>')) {
  999.                 inTag = false;
  1000.             } else if (!inTag) {
  1001.                 output += c;
  1002.             }
  1003.         }
  1004.         return output;
  1005.     } else {
  1006.         return s;
  1007.     }
  1008. }
  1009.  
  1010. function getNumResultsPerPage() {
  1011.     if (scSearchEngine == 'craigslist') {
  1012.         return scNumCraigslistResultsPerPage;
  1013.     }
  1014.  
  1015.     var num = 10;
  1016.  
  1017.     var cookieParts = scGetDocument().cookie.split('; ');
  1018.     for (var i = 0; i < cookieParts.length; i++) {
  1019.         var cookiePart = cookieParts[i];
  1020.         if (scSearchEngine == 'yahoo' && !startsWith(cookiePart, 'sS=')) {
  1021.             continue;
  1022.         }
  1023.  
  1024.         var pos = cookiePart.indexOf(scNumResultsToken);
  1025.         if (pos > 0) {
  1026.             num = parseInt(cookiePart.substring(pos + scNumResultsToken.length));
  1027.             break;
  1028.         }
  1029.     }
  1030.  
  1031.     return num;
  1032. }
  1033.  
  1034. function inNewWindowMode() {
  1035.     var inNewWindowMode = false;
  1036.     if ((typeof scCookieNewWindowToken != 'undefined') && scCookieNewWindowToken) {
  1037.         var cookieParts = scGetDocument().cookie.split('; ');
  1038.         for (var i = 0; i < cookieParts.length; i++) {
  1039.             var cookiePart = cookieParts[i];
  1040.             if (contains(cookiePart, scCookieNewWindowToken)) {
  1041.                 inNewWindowMode = true;
  1042.                 break;
  1043.             }
  1044.         }
  1045.     } else if (scSearchEngine == 'lexis') {
  1046.         inNewWindowMode = true;
  1047.     }
  1048.  
  1049.     return inNewWindowMode;
  1050. }
  1051.  
  1052. function linkClickOpensNewWindow(event) {
  1053.     return (event.shiftKey || event.ctrlKey || event.metaKey) ? true : inNewWindowMode();
  1054. }
  1055.  
  1056. function getSerpUrl() {
  1057.     // make a new copy of window.location
  1058.     return '' + window.location;
  1059. }
  1060.  
  1061. function getSSMapKey() {
  1062.     return getUrlHash(getSerpUrl());
  1063. }
  1064.  
  1065. function searchEngineQueryURL(searchString, numToGet, startNum) {
  1066.     var url = 'http://' + scCurrentPageDomain;
  1067.  
  1068.     var loc = scIsFF ? window.top.location : window.location;
  1069.     var argsString = loc.search.substring(1);
  1070.  
  1071.     if ((scSearchEngine == 'craigslist') && (argsString == '')) {
  1072.         url += window.location.pathname;
  1073.         if (startNum > 0) {
  1074.              url += ('index' + startNum + '.html');
  1075.         }
  1076.     } else {
  1077.         // google search string comes from a link, so it's already encoded
  1078.         if (scSearchEngine != 'google') {
  1079.             searchString = encodeURIComponent(searchString);
  1080.         }
  1081.  
  1082.         url += ('/' + scSearchQueryCommand + '?' + scSearchQueryTermArgName + '=' + searchString);
  1083.         if (scSearchQueryNumResultsArgName) {
  1084.             url += ('&' + scSearchQueryNumResultsArgName + '=' + numToGet);
  1085.         }
  1086.         if (!(scSearchEngine == 'craigslist' && startNum == 0)) {
  1087.             if (scSearchQueryStartResultArgName) {
  1088.                 url += ('&' + scSearchQueryStartResultArgName + '=' + startNum);
  1089.             }
  1090.         }
  1091.  
  1092.         var args = argsString.split('&');
  1093.         for (i = 0; i < args.length; i++) {
  1094.             var arg = args[i];
  1095.             var sepPos = arg.indexOf('=');
  1096.             if (sepPos != -1) {
  1097.                 var name = arg.substring(0, sepPos);
  1098.                 var value = arg.substring(sepPos + 1);
  1099.                 if (name != scSearchQueryTermArgName &&
  1100.                         name != scSearchQueryNumResultsArgName &&
  1101.                         name != scSearchQueryStartResultArgName) {
  1102.                     url = url + '&' + name + '=' + value;
  1103.                 }
  1104.             } else {
  1105.                 url = url + '&' + arg;
  1106.             }
  1107.         }
  1108.     }
  1109.  
  1110.     return url;
  1111. }
  1112.  
  1113. function isCustomSearch(pathname) {
  1114.     return startsWith(pathname, '/cse') || startsWith(pathname, '/custom');
  1115. }
  1116.  
  1117. function uploadSRs() {
  1118.     if (scUploadResults && scNumSRsForInitialUpload) {
  1119.         var startNum = (scBatchNum - 1) * scBatchSize;
  1120.         var url = searchEngineQueryURL(scSearchString, scBatchSize, startNum);
  1121.         ajax({    method: 'GET',
  1122.             url: url,
  1123.             onload: function(xhr) {
  1124.                 var html = getResponseText(xhr);
  1125.                 if (html.match(/<html/i) || html.match(/<!doctype html/i)) {
  1126.                     doUploadSRs(html);
  1127.                 } else {
  1128.                     undoUIChanges('uploadSRs');
  1129.                 }
  1130.             }
  1131.         });
  1132.     }
  1133. }
  1134.  
  1135. function doUploadSRs(html) {
  1136.     var northAdDomains = (typeof scGetNorthAdDomains == 'function') ? scGetNorthAdDomains() : null;
  1137.     var southAdDomains = (typeof scGetSouthAdDomains == 'function') ? scGetSouthAdDomains() : null;
  1138.     var eastAdDomains = (typeof scGetEastAdDomains == 'function') ? scGetEastAdDomains() : null;
  1139.  
  1140.     ajax({    method: 'POST',
  1141.         url: scHost + 'search/upload',
  1142.         headers: {'Content-type': 'application/x-www-form-urlencoded'},
  1143.         data:    'ssMapKey=' + getSSMapKey() +
  1144.             '&instId=' + scInstId +
  1145.             '&extensionVersion=' + scExtensionVersion +
  1146.             (northAdDomains ? ('&northAdDomains=' + northAdDomains) : '') +
  1147.             (southAdDomains ? ('&southAdDomains=' + southAdDomains) : '') +
  1148.             (eastAdDomains ? ('&eastAdDomains=' + eastAdDomains) : '') +
  1149.             '&srPayloadHtml=' + encodeURIComponent(html),
  1150.         onload: function(xhr) {
  1151.             var text = getResponseText(xhr);
  1152.             if (!isServerError(text)) {
  1153.                 var xmlRoot = xmlParser(text);
  1154.                 var data = xmlRoot.getElementsByTagName('data')[0];
  1155.                 if (data) {
  1156.                     if (!scFirstBatchReceived) {
  1157.                         scFirstBatchReceived = true;
  1158.     
  1159.                         var node = data.getElementsByTagName('moreResultsAvailable')[0];
  1160.                         if (getText(node) != '1') {
  1161.                             removeMoreResultsLinks();
  1162.                         }
  1163.     
  1164.                         node = data.getElementsByTagName('notEnoughResults')[0];
  1165.                         if ((getText(node) == '1') && !justDoingCraigslistImages()) {
  1166.                             undoUIChanges('doUploadSRs1');
  1167.                         }
  1168.                     }
  1169.  
  1170.                     if (scBufferedEvent) {
  1171.                         clickHandler(scBufferedEvent);
  1172.                         scBufferedEvent = null;
  1173.                     }
  1174.     
  1175.                     if (typeof scGetSnippetsToUpload == 'function') {
  1176.                         scGetSnippetsToUpload(html);
  1177.                     } else {
  1178.                         scNumBatchesLeftToUpload--;
  1179.                         if (scNumBatchesLeftToUpload > 0) {
  1180.                             scBatchNum++;
  1181.                             uploadSRs();
  1182.                         }
  1183.                     }
  1184.                 }
  1185.             } else {
  1186.                 if (scBatchNum == 1) {
  1187.                     log('error in upload', true);
  1188.                     undoUIChanges('doUploadSRs2');
  1189.                 }
  1190.             }
  1191.         },
  1192.         onerror: function() {
  1193.             if (scBatchNum == 1) {
  1194.                 log('error in upload', true);
  1195.                 undoUIChanges('doUploadSRs3');
  1196.             }
  1197.         }
  1198.     });
  1199. }
  1200.  
  1201. function uploadMoreSRs() {
  1202.     if (scUploadResults && ((scBatchNum + 1) * scBatchSize <= scMaxSRsToUpload)) {
  1203.         scBatchNum++;
  1204.         uploadSRs();
  1205.     }
  1206. }
  1207.  
  1208. function getSnippetTracker(url) {
  1209.     if (scSnippetTrackers) {
  1210.         var numSnippets = scSnippetTrackers.length;
  1211.         for (var i = 0; i < numSnippets; i++) {
  1212.             var tracker = scSnippetTrackers[i];
  1213.             if (tracker && endsWith(url, tracker.url)) {
  1214.                 return tracker;
  1215.             }
  1216.         }
  1217.     }
  1218.     return null;
  1219. }
  1220.  
  1221. function fetchSnippets(snippetBatchNum) {
  1222.     var startIndex = snippetBatchNum * scSnippetBatchSize;
  1223.     var endIndex = startIndex + scSnippetBatchSize;
  1224.  
  1225.     for (var i = startIndex; i < endIndex; i++) {
  1226.         var tracker = scSnippetTrackers[i];
  1227.         if (!tracker) {
  1228.             continue;
  1229.         }
  1230.  
  1231.         var url = tracker.url;
  1232.         if (!url || tracker.requestDispatched) {
  1233.             continue;
  1234.         }
  1235.  
  1236.         tracker.requestDispatched = true;
  1237.         if (scSearchEngine == 'craigslist') {
  1238.             url = 'http://' + window.location.host + url;
  1239.         }
  1240.         ajax({    method: 'GET',
  1241.             url: url,
  1242.             vars: {'snippetBatchNum': snippetBatchNum.toString()},
  1243.             onload: function(xhr) {
  1244.                 var tracker = getSnippetTracker(xhr.url);
  1245.                 if (tracker) {
  1246.                     tracker.snippet = removeSimpleHtmlTags(getResponseText(xhr), true);
  1247.                 }
  1248.  
  1249.                 snippetsPhase2(snippetBatchNum);
  1250.             },
  1251.             onerror: function(xhr) {
  1252.                 log('request failed for ' + xhr.url, true);
  1253.  
  1254.                 var tracker = getSnippetTracker(xhr.url);
  1255.                 if (tracker) {
  1256.                     tracker.requestFailed = true;
  1257.                 }
  1258.  
  1259.                 snippetsPhase2(snippetBatchNum);
  1260.             }
  1261.         });
  1262.     }
  1263. }
  1264.  
  1265. function snippetsPhase2(snippetBatchNum) {
  1266.     var startIndex = snippetBatchNum * scSnippetBatchSize;
  1267.     var endIndex = startIndex + scSnippetBatchSize;
  1268.  
  1269.     for (var i = startIndex; i < endIndex; i++) {
  1270.         var tracker = scSnippetTrackers[i];
  1271.         if (tracker && tracker.requestDispatched && !tracker.requestFailed && !tracker.snippet) {
  1272.             return;
  1273.         }
  1274.     }
  1275.  
  1276.     var payload = '<payload>';
  1277.     var foundSome = false;
  1278.     var ssMapKey = getSSMapKey();
  1279.     for (var i = startIndex; i < endIndex; i++) {
  1280.         var tracker = scSnippetTrackers[i];
  1281.         if (tracker && tracker.url && tracker.snippet && (tracker.ssMapKey == ssMapKey)) {
  1282.             var sr = '<sr>\n' +
  1283.                 '<url><![CDATA[' + tracker.url + ']]></url>\n' +
  1284.                 '<snippet><![CDATA[' + tracker.snippet + ']]></snippet>\n' +
  1285.                 '</sr>\n';
  1286.             payload += sr;
  1287.             foundSome = true;
  1288.         }
  1289.     }
  1290.     payload += '</payload>\n';
  1291.  
  1292.     if (!foundSome) {
  1293.         return;
  1294.     }
  1295.  
  1296.     if (getAffectCraigslist()) {
  1297.         uploadSnippets(snippetBatchNum, payload);
  1298.     } else if (getAddCLImagePreviews()) {
  1299.         for (var i = startIndex; i < endIndex; i++) {
  1300.             var tracker = scSnippetTrackers[i];
  1301.             if (tracker) {
  1302.                 if (tracker.snippet && !tracker.snippetProcessed) {
  1303.                     try {
  1304.                         tracker.snippetProcessed = true;
  1305.                         scProcessSnippet(tracker.url, tracker.snippet);
  1306.                     } catch (e) {
  1307.                         log('error processing snippet for ' + tracker.url + ': ' + e.message, true);
  1308.                     }
  1309.                 }
  1310.  
  1311.                 scSnippetTrackers[i] = null;
  1312.             }
  1313.         }
  1314.  
  1315.         if (endIndex < scSnippetTrackers.length) {
  1316.             fetchSnippets(snippetBatchNum + 1);
  1317.         } else {
  1318.             scNumBatchesLeftToUpload--;
  1319.             if (scNumBatchesLeftToUpload > 0) {
  1320.                 scBatchNum++;
  1321.                 uploadSRs();
  1322.             }
  1323.         }
  1324.     }
  1325. }
  1326.  
  1327. function uploadSnippets(snippetBatchNum, payload) {
  1328.     var startIndex = snippetBatchNum * scSnippetBatchSize;
  1329.     var endIndex = startIndex + scSnippetBatchSize;
  1330.  
  1331.     ajax({    method: 'POST',
  1332.         url: scHost + 'search/uploadSnippets',
  1333.         headers: {'Content-type': 'application/x-www-form-urlencoded'},
  1334.         data:    'ssMapKey=' + getSSMapKey() +
  1335.             '&instId=' + scInstId +
  1336.             '&extensionVersion=' + scExtensionVersion +
  1337.             '&payload=' + encodeURIComponent(payload),
  1338.         vars: {'startIndex': startIndex.toString(), 'endIndex': endIndex.toString(), 'snippetBatchNum': snippetBatchNum.toString()},
  1339.         onload: function(xhr) {
  1340.             for (var i = startIndex; i < endIndex; i++) {
  1341.                 var tracker = scSnippetTrackers[i];
  1342.                 if (tracker) {
  1343.                     if (tracker.snippet && !tracker.snippetProcessed) {
  1344.                         try {
  1345.                             tracker.snippetProcessed = true;
  1346.                             scProcessSnippet(tracker.url, tracker.snippet);
  1347.                         } catch (e) {
  1348.                             log('error processing snippet for ' + tracker.url + ': ' + e.message, true);
  1349.                         }
  1350.                     }
  1351.  
  1352.                     var id = "scBullseye" + getUrlHash(tracker.url);
  1353.                     var bullseye = scGetDocument().getElementById(id);
  1354.                     if (bullseye) {
  1355.                         bullseye.style.visibility = "visible";
  1356.                     }
  1357.  
  1358.                     scSnippetTrackers[i] = null;
  1359.                 }
  1360.             }
  1361.  
  1362.             var failed = addMoreResultsLinks();
  1363.             if (!failed) {
  1364.                 if (endIndex < scSnippetTrackers.length) {
  1365.                     fetchSnippets(snippetBatchNum + 1);
  1366.                 } else {
  1367.                     scNumBatchesLeftToUpload--;
  1368.                     if (scNumBatchesLeftToUpload > 0) {
  1369.                         scBatchNum++;
  1370.                         uploadSRs();
  1371.                     }
  1372.                 }
  1373.             }
  1374.         }
  1375.     });
  1376. }
  1377.  
  1378. function haveSRContaining(word, maxToCheck) {
  1379.     var lastIndex = Math.min(maxToCheck, scSRNodes.length);
  1380.     for (var i = 0; i < lastIndex; i++) {
  1381.         var srNode = scSRNodes[i];
  1382.         var text = srNode.innerHTML.toLowerCase();
  1383.         if (contains(text, word)) {
  1384.             return true;
  1385.         }
  1386.     }
  1387.     return false;
  1388. }
  1389.  
  1390. function getSRByUrlHash(urlHash) {
  1391.     var srNode;
  1392.  
  1393.     if (startsWith(urlHash, 'www')) {
  1394.         urlHash = urlHash.substring(3);
  1395.     }
  1396.  
  1397.     var numNodes = scSRNodes.length;
  1398.     for (var i = 0; i < numNodes; i++) {
  1399.         var thisSrNode = scSRNodes[i];
  1400.         var thisUrlHash = getUrlHash(scExtractUrlFromSRNode(thisSrNode));
  1401.         if (startsWith(thisUrlHash, 'www')) {
  1402.             thisUrlHash = thisUrlHash.substring(3);
  1403.         }
  1404.         if (thisUrlHash == urlHash) {
  1405.             srNode = thisSrNode;
  1406.             break;
  1407.         }
  1408.     }
  1409.  
  1410.     if (!srNode) {
  1411.         for (var i = 0; i < numNodes; i++) {
  1412.             var thisSrNode = scSRNodes[i];
  1413.             var thisUrlHash = getUrlHash(scExtractUrlFromSRNode(thisSrNode));
  1414.             if (startsWith(thisUrlHash, 'www')) {
  1415.                 thisUrlHash = thisUrlHash.substring(3);
  1416.             }
  1417.             if (startsWith(thisUrlHash, urlHash)) {
  1418.                 srNode = thisSrNode;
  1419.                 break;
  1420.             }
  1421.         }
  1422.     }
  1423.  
  1424.     return srNode;
  1425. }
  1426.  
  1427. function getSRByUrlFragment(urlFragment) {
  1428.     var srNode;
  1429.  
  1430.     var numNodes = scSRNodes.length;
  1431.     for (var i = 0; i < numNodes; i++) {
  1432.         var thisSrNode = scSRNodes[i];
  1433.         var thisUrl = scExtractUrlFromSRNode(thisSrNode);
  1434.         if (thisUrl.indexOf(urlFragment) != -1) {
  1435.             srNode = thisSrNode;
  1436.             break;
  1437.         }
  1438.     }
  1439.  
  1440.     return srNode;
  1441. }
  1442.  
  1443. function getRecsSpan(urlHash) {
  1444.     var span = scGetDocument().getElementById('scRecs' + urlHash);
  1445.     if (!span) {
  1446.                if (startsWith(urlHash, 'www')) {
  1447.             urlHash = urlHash.substring(3);
  1448.             span = scGetDocument().getElementById('scRecs' + urlHash);
  1449.         } else {
  1450.             span = scGetDocument().getElementById('scRecswww' + urlHash);
  1451.         }
  1452.     }
  1453.     return span;
  1454. }
  1455.  
  1456. function updateRecsInUI(urlHash, recs, messageIfNone, isBullseye) {
  1457.     var haveRecs = (recs && recs.length > 10);
  1458.     var span = getRecsSpan(urlHash);
  1459.     if (span) {
  1460.         if (haveRecs) {
  1461.             if (scDoAnimatedRecs) {
  1462.                 span.innerHTML = "<table id='scAnimatedRecs" + urlHash + "'>"  +  recs  +  "</table><div id='SETscRecs" + urlHash + "' style='clear:both;'></div>";
  1463.                 animateRecs('scAnimatedRecs' + urlHash,'scRecs' + urlHash);
  1464.             } else {
  1465.                 span.innerHTML = "<table>" + recs + "</table>";
  1466.             }
  1467.  
  1468.             scAddResetRecs();
  1469.             if (scIsFF && !isBullseye) {
  1470.                 showNotification(getMessage('RECS_NOTIFICATION'), 1);
  1471.             }
  1472.             updateWOT();
  1473.         } else if (messageIfNone) {
  1474.             var msg = getMessage('NO_RECS');
  1475.             span.innerHTML = "<table style='font-size: 14px; position:relative; left:99px;'><tr><td><i>" + msg + "</i></td></tr></table>";
  1476.         }
  1477.     }
  1478. }
  1479.  
  1480. function updateUIAfterSelection(data, displayRecs, urlHash, gesture) {
  1481.     if (displayRecs && !getAllDisabled() && !justDoingCraigslistImages()) {
  1482.         var srNode = getChildrenByTagAndAttribute(scGetDocument().body, null, 'scUrlHash', urlHash)[0];
  1483.         var recs = getText(data.getElementsByTagName('recs')[0]);
  1484.         if (srNode) {
  1485.             var srContainsBullseye = contains(srNode.innerHTML, '/bullseye.bmp');
  1486.             var isBullseye = (gesture == 'bullseye');
  1487.             updateRecsInUI(urlHash, recs, srContainsBullseye && isBullseye, isBullseye);
  1488.         }
  1489.  
  1490.         if (typeof scSearchResultSelectedFollowup == 'function') {
  1491.             scSearchResultSelectedFollowup(data, displayRecs, urlHash, gesture);
  1492.         }
  1493.     }
  1494. }
  1495.  
  1496. var divCurrent;
  1497. var top = 0;
  1498. var left = 25;
  1499. function animateRecs(id,innerSpan){
  1500.     if (divCurrent != 'SET' + innerSpan + '') {
  1501.         $('#' + divCurrent).html('');
  1502.     }
  1503.     top_div = top;
  1504.     if (top_div == 0) {
  1505.         top_div = document.getElementById(innerSpan).offsetTop + 25;
  1506.     }
  1507.     document.getElementById('SET' + innerSpan).style.position = 'absolute';
  1508.     $('#SET' + innerSpan).animate({top:"" + top_div + "px"}, {queue: false, duration: 350}); 
  1509.     document.getElementById('SET' + innerSpan).style.backgroundColor = '#BDF381';
  1510.     $('#SET' + innerSpan).html($('#' + id).html());
  1511.     divCurrent = 'SET' + innerSpan;
  1512.     
  1513.     $('.scBullseye').click(function(e){
  1514.          top = e.pageY + 40;
  1515.     });
  1516.     
  1517.     return false;
  1518.  
  1519. function getRecs(urlHash, displayRecs, gesture, openNewWindow) {
  1520.     if (scGettingRecs || getAllDisabled()) {
  1521.         return;
  1522.     }
  1523.  
  1524.     scGettingRecs = true;
  1525.  
  1526.     var maxNumRecs = ((gesture == 'click' || gesture == 'rightClick') && !getShowRecsOnSRClick()) ? 0 : getMaxNumRecsForSRSelection();
  1527.     ajax({    method: 'GET',
  1528.         url: scHost + 'search/selectSearchResult?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion + '&gesture=' + gesture + '&maxNumRecs=' + maxNumRecs + '&urlHash=' + urlHash + '&openNewWindow=' + (openNewWindow ? '1' : '0'),
  1529.         vars: {'displayRecs': displayRecs.toString(), 'urlHash': "'"+urlHash.toString()+"'", 'gesture': "'"+gesture.toString()+"'"},
  1530.         onload: function(xhr) {
  1531.             try {
  1532.                 var text = getResponseText(xhr);
  1533.                 if (text && !isServerError(text)) {
  1534.                     var xmlRoot = xmlParser(text);
  1535.                     var data = xmlRoot.getElementsByTagName('data')[0];
  1536.                     if (data) {
  1537.                         updateUIAfterSelection(data, displayRecs, urlHash, gesture);
  1538.  
  1539.                         scSRSelectionCount++;
  1540.                         if (scSRSelectionCount == 3) {
  1541.                             scSRSelectionCount = 0;
  1542.                             uploadMoreSRs();
  1543.                         }
  1544.                     }
  1545.                 }
  1546.             } catch (e) {
  1547.                 log('error getting recs: ' + e.message, true);
  1548.             } finally {
  1549.                 scGettingRecs = false;
  1550.             }
  1551.         },
  1552.         onerror: function() {
  1553.             scGettingRecs = false;
  1554.             log('error getting recs', true);
  1555.             undoUIChanges('getRecs');
  1556.         }
  1557.     });
  1558. }
  1559.  
  1560. function closeRecs(urlHash) {
  1561.     ajax({    method: 'GET',
  1562.         url: scHost + 'search/closeRecs?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion + '&urlHash=' + urlHash
  1563.     });
  1564.  
  1565.     var span = getRecsSpan(urlHash)
  1566.     if (span) {
  1567.         span.innerHTML = '';
  1568.     }
  1569. }
  1570.  
  1571. function nuke(node) {
  1572.     if (node) {
  1573.         node.innerHTML = '';
  1574.         node.parentNode.removeChild(node);
  1575.     }
  1576. }
  1577.  
  1578. function resetRecs() {
  1579.     ajax({    method: 'GET',
  1580.         url: scHost + 'search/resetRecs?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion
  1581.     });
  1582.  
  1583.     scRecsWereReset = true;
  1584.     scSRSelectionCount = 0;
  1585.  
  1586.     for (var i = 0; i < scSRNodes.length; i++) {
  1587.         var srNode = scSRNodes[i];
  1588.         var url = scExtractUrlFromSRNode(srNode);
  1589.         if (url) {
  1590.             var urlHash = getUrlHash(url);
  1591.             var span = getRecsSpan(urlHash);
  1592.             if (span) {
  1593.                 span.innerHTML = '';
  1594.             }
  1595.         }
  1596.     }
  1597.  
  1598.     scUpdateResultCount();
  1599.  
  1600.     var originalInsertPoint = getElementsByTagAndAttribute("div", "scOriginalInsertPoint", "1")[0];
  1601.     removeChildren(originalInsertPoint);
  1602.     originalInsertPoint.setAttribute('id', 'scInsertPoint');
  1603.     nuke(scGetDocument().getElementById('scRecLinksLabel'));
  1604. }
  1605.  
  1606. function removeMoreResultsLinks() {
  1607.     var aTags = getElementsByTagAndClass("a", "scMoreResults");
  1608.     for (var i = 0; i < aTags.length; i++) {
  1609.         var aTag = aTags[i];
  1610.         aTag.parentNode.removeChild(aTag);
  1611.     }
  1612. }
  1613.  
  1614. function insertMoreResults(text) {
  1615.     var insertPoint = scGetDocument().getElementById('scInsertPoint');
  1616.     insertPoint.innerHTML = text;
  1617.     if (scIsIE) {
  1618.         insertPoint.scrollIntoView();
  1619.     }
  1620.     insertPoint.id = '';
  1621.     updateWOT();
  1622. }
  1623.  
  1624. function moreResults() {
  1625.     if (scGettingMoreResults) {
  1626.         return;
  1627.     }
  1628.  
  1629.     scGettingMoreResults = true;
  1630.     if (scGetDocument().getElementById('scInsertPoint')) {
  1631.         ajax({    method: 'GET',
  1632.             url: scHost + 'search/moreResults?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion,
  1633.             onload: function(xhr) {
  1634.                 try {
  1635.                     var text = getResponseText(xhr);
  1636.                     if (text && !isServerError(text)) {
  1637.                         insertMoreResults(text);
  1638.                         scUpdateResultCount();
  1639.                         scAddResetRecs();
  1640.     
  1641.                         scSRSelectionCount = 0;
  1642.                         uploadMoreSRs();
  1643.     
  1644.                         if (contains(text, '<!--NO_MORE_RESULTS-->')) {
  1645.                             removeMoreResultsLinks();
  1646.                         }
  1647.  
  1648.                         if (scIsFF && scSearchEngine != 'craigslist') {
  1649.                             showNotification(getMessage('PAGE_NOTIFICATION'), 2);
  1650.                         }
  1651.  
  1652.                         for (var pageNum = 99; pageNum >= 0; pageNum--) {
  1653.                             var nodeId = 'scPageSeparator' + pageNum;
  1654.                             if (scGetDocument().getElementById(nodeId)) {
  1655.                                 focusOnNode(nodeId);
  1656.                                 break;
  1657.                             }
  1658.                         }
  1659.                     } else {
  1660.                         log('error getting more results', true);
  1661.                         undoUIChanges('moreResults1');
  1662.                     }
  1663.                 } catch (e) {
  1664.                     log('error getting more results: ' + e.message, true);
  1665.                 } finally {
  1666.                     scGettingMoreResults = false;
  1667.                 }
  1668.             },
  1669.             onerror: function() {
  1670.                 scGettingMoreResults = false;
  1671.                 log('error getting more results', true);
  1672.                 undoUIChanges('moreResults2');
  1673.             }
  1674.         });
  1675.     }
  1676. }
  1677.  
  1678. function goToPage(start) {
  1679.     if (scGoingToPage) {
  1680.         return;
  1681.     }
  1682.  
  1683.     scGoingToPage = true;
  1684.     if (scGetDocument().getElementById('scInsertPoint')) {
  1685.         ajax({    method: 'GET',
  1686.             url: scHost + 'search/goToPage?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion + '&start=' + start,
  1687.             vars: {'start': start.toString()},
  1688.             onload: function(xhr) {
  1689.                 try {
  1690.                     var text = getResponseText(xhr);
  1691.                     if (text && !isServerError(text)) {
  1692.                         if (text.length > 10) {
  1693.                             insertMoreResults(text); 
  1694.                             scUpdateResultCount();
  1695.                             scAddResetRecs();
  1696.     
  1697.                             scSRSelectionCount = 0;
  1698.                             uploadMoreSRs();
  1699.  
  1700.                             if (scIsFF && scSearchEngine != 'craigslist') {
  1701.                                 showNotification(getMessage('PAGE_NOTIFICATION'), 2);
  1702.                             }
  1703.  
  1704.                             var newPageNum = Math.round(start / getNumResultsPerPage()) + 1;
  1705.                             focusOnNode('scPageSeparator' + newPageNum);
  1706.                         }
  1707.                     } else {
  1708.                         log('error going to page', true);
  1709.                         undoUIChanges('goToPage1');
  1710.                     }
  1711.                 } catch (e) {
  1712.                     log('error going to page: ' + e.message, true);
  1713.                 } finally {
  1714.                     scGoingToPage = false;
  1715.                 }
  1716.             },
  1717.             onerror: function() {
  1718.                 scGoingToPage = false;
  1719.                 log('error going to page', true);
  1720.                 undoUIChanges('goToPage2');
  1721.             }
  1722.         });
  1723.     }
  1724. }
  1725.  
  1726. function clickHandler(event) {
  1727.     try {
  1728.         var ready = true;
  1729.         if (scUploadResults && (!scFirstBatchReceived && !scContinuingSession)) {
  1730.             scBufferedEvent = scIsIE ? new EventRecord(event) : event;
  1731.             ready = false;
  1732.         }
  1733.  
  1734.         var node = scIsIE ? event.srcElement : event.target;
  1735.         var parentNode = node.parentNode;
  1736.         var tagName = node.tagName;
  1737.         if (!tagName) {
  1738.             tagName = node.getAttribute('tagName');
  1739.         }
  1740.         var className = node.className;
  1741.         if (!className) {
  1742.             className = node.getAttribute('class');
  1743.         }
  1744.  
  1745.         var rightClick;
  1746.         if (event.which) {
  1747.             rightClick = (event.which == 3);
  1748.         } else if (event.button) {
  1749.             rightClick = (event.button == 2);
  1750.         }
  1751.  
  1752.         if (className) {
  1753.             if (className == 'scMoreResults') {
  1754.                 moreResults();
  1755.                 cancelEvent(event);
  1756.                 return;
  1757.             } else if (className == 'scResetRecs') {
  1758.                 resetRecs();
  1759.                 return;
  1760.             } else if (className == 'scLexisBullseye') {
  1761.                 var recs = scGetDocument().getElementById('scLexisRecs');
  1762.                 if (recs) {
  1763.                     recs.style.display = (recs.style.display == 'block') ? 'none' : 'block';
  1764.                 }
  1765.                 return;
  1766.             }
  1767.         }
  1768.  
  1769.         var url;
  1770.         var urlHash;
  1771.         var anchorText;
  1772.         var isAd = false;
  1773.         var isSCNewsItem = false;
  1774.         var partnerHandler = null;
  1775.         var isInLink = false;
  1776.         var isNextPageLink = false;
  1777.         var gotoPageStartVal = 0;
  1778.         while (node && node.getAttribute) {
  1779.             if (!isInLink) {
  1780.                 var text = node.toString();
  1781.                 isInLink = (startsWith(text, 'http') || startsWith(text, 'ftp'));
  1782.                 if (isInLink) {
  1783.                     anchorText = node.text;
  1784.                     url = text;
  1785.                 }
  1786.             }
  1787.  
  1788.             var id = '';
  1789.             try {
  1790.                 id = node.getAttribute('id');
  1791.  
  1792.                 if ((scSearchEngine == 'lexis') && startsWith(id, 'NextButton')) {
  1793.                     isNextPageLink = true;
  1794.                 }
  1795.             } catch (e) {
  1796.             }
  1797.  
  1798.             if (!urlHash) {
  1799.                 urlHash = node.getAttribute('scUrlHash');
  1800.             }
  1801.             if (!isAd) {
  1802.                 try {
  1803.                     isAd = isAdSectionDiv(node, id);
  1804.                 } catch (e) {
  1805.                 }
  1806.             }
  1807.             if (!isSCNewsItem) {
  1808.                 isSCNewsItem = (id == 'scNewsBlock');
  1809.             }
  1810.             if (!partnerHandler) {
  1811.                 partnerHandler = node.getAttribute('partnerHandler');
  1812.             }
  1813.  
  1814.             if (!(isNextPageLink || gotoPageStartVal) && (node.tagName == 'A')) {
  1815.                 try {
  1816.                     var linkType = scLinkType(node);
  1817.                     if (linkType == 'Next') {
  1818.                         isNextPageLink = true;
  1819.                     } else if (linkType == 'Goto') {
  1820.                         gotoPageStartVal = node.getAttribute('scGotoPageStartVal');
  1821.                     }
  1822.                 } catch (e) {
  1823.                     log(e.message);
  1824.                 }
  1825.             }
  1826.  
  1827.     
  1828.             node = node.parentNode;
  1829.         }
  1830.  
  1831.         if (isNextPageLink) {
  1832.             log('next page, ready: ' + ready);
  1833.             cancelEvent(event);
  1834.             if (ready) {
  1835.                 moreResults();
  1836.                 scNumUserActions++;
  1837.             }
  1838.             return;
  1839.         } else if (gotoPageStartVal) {
  1840.             log('goto page, ready: ' + ready);
  1841.             cancelEvent(event);
  1842.             if (ready) {
  1843.                 goToPage(gotoPageStartVal);
  1844.                 scNumUserActions++;
  1845.             }
  1846.             return;
  1847.         }
  1848.     
  1849.         var clickedLink = (tagName == 'A' || isInLink);
  1850.         var openNewWindow = linkClickOpensNewWindow(event);
  1851.         if (urlHash) {
  1852.             if (clickedLink) {
  1853.                 getRecs(urlHash, ready && (rightClick || openNewWindow), rightClick ? 'rightClick' : 'click', openNewWindow);
  1854.                 var span = getRecsSpan(urlHash);
  1855.                 if (span) {
  1856.                     incNumResultsClicked();
  1857.  
  1858.                     if (scNumUserActions > 0) {
  1859.                         incNumResultsClickedWhenRecsAvailable();
  1860.                     }
  1861.                     scNumUserActions++;
  1862.  
  1863.                     if (span.getAttribute('srType') == 'rec') {
  1864.                         incNumRecsClicked();
  1865.                     }
  1866.                 }
  1867.             } else if (tagName == 'IMG') {
  1868.                 if (className == 'scClose') {
  1869.                     closeRecs(urlHash);
  1870.                 } else if (className == 'scBullseye') {
  1871.                     var now = (new Date()).getTime();
  1872.                     if (now - scLastBullseyeClick > 100) {
  1873.                         scLastBullseyeClick = now;
  1874.                         var span = getRecsSpan(urlHash);
  1875.                         if (span.innerHTML.length < 20) {
  1876.                             getRecs(urlHash, ready, 'bullseye', false);
  1877.                         } else {
  1878.                             closeRecs(urlHash);
  1879.                         }
  1880.                     }
  1881.                 }
  1882.             }
  1883.         } else if (isAd) {
  1884.             if (!scAdStatus) {
  1885.                 scAdStatus = 1;
  1886.                 setAdStatus(scAdStatus);
  1887.             }
  1888.         } else if (clickedLink && url) {
  1889.             ajax({    method: 'GET',
  1890.                 url: scHost + 'search/linkClick?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion + '&url=' + encodeURIComponent(url) + '&openNewWindow=' + (openNewWindow ? '1' : '0') + '&isSCNewsItem=' + (isSCNewsItem ? 1 : 0)  + (partnerHandler ? ('&partnerHandler=' +  partnerHandler) : '')
  1891.             });
  1892.         }
  1893.     } catch (e) {
  1894.         log('error in click handler: ' + e.message, true);
  1895.     }
  1896. }
  1897.  
  1898. function removeProtocol(url) {
  1899.     var pos = url.indexOf('://');
  1900.     if (pos != -1) {
  1901.         url = url.substring(pos + 3);
  1902.     }
  1903.     return url;
  1904. }
  1905.  
  1906. function getUrlHash(url) {
  1907.     var urlHash = '';
  1908.  
  1909.     if (url) {
  1910.         url = decodeEntities(url);
  1911.  
  1912.         var len = url.length;
  1913.         for (var i = 0; i < len; i++) {
  1914.             var c = url.charAt(i);
  1915.             if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '$') || (c == '-') || (c == '_') || (c == '!') || (c == '*') || (c == '(') || (c == ')')) {
  1916.                 urlHash += c;
  1917.             }
  1918.         }
  1919.     }
  1920.  
  1921.     return urlHash;
  1922. }
  1923.  
  1924. function undoUIChanges(where) {
  1925.     log('undo: ' + where);
  1926.     if (scSearchEngine == 'craigslist') {
  1927.         if (typeof scOrigPage != 'undefined') {
  1928.             scGetDocument().body.innerHTML = scOrigPage;
  1929.         }
  1930.     } else {
  1931.         var navbar = getNavbar1();
  1932.         var navbar2 = getNavbar2();
  1933.  
  1934.         var nodes = getChildren(navbar, 'a');
  1935.         for (var i = 0; i < nodes.length; i++) {
  1936.             scRestoreHref(nodes[i]);
  1937.         }
  1938.  
  1939.         nodes = getChildren(navbar2, 'a');
  1940.         for (var i = 0; i < nodes.length; i++) {
  1941.             scRestoreHref(nodes[i]);
  1942.         }
  1943.     }
  1944.  
  1945.     var bullseyes = getElementsByTagAndClass("img", "scBullseye");
  1946.     for (var i = 0; i < bullseyes.length; i++) {
  1947.         var bullseye = bullseyes[i];
  1948.         bullseye.parentNode.removeChild(bullseye);
  1949.     }
  1950.  
  1951.     if (scIsIE) {
  1952.         scGetDocument().detachEvent('onmouseup');
  1953.     } else {
  1954.         scGetDocument().removeEventListener('click', clickHandler, true);
  1955.     }
  1956. }
  1957.  
  1958. function focusOnNode(id) {
  1959.     var nodeToFocus = scGetDocument().getElementById(id);
  1960.     if (nodeToFocus) {
  1961.         nodeToFocus.scrollIntoView();
  1962.     }
  1963. }
  1964.  
  1965. function updateUIAfterRefresh(data) {
  1966.     if (getAllDisabled() || justDoingCraigslistImages()) {
  1967.         return;
  1968.     }
  1969.  
  1970.     var javascriptNode = data.getElementsByTagName('javascript')[0];
  1971.     if (javascriptNode) {
  1972.         var js = getText(javascriptNode);
  1973.         if (js) {
  1974.             eval(js);
  1975.             initUI();
  1976.         }
  1977.     }
  1978.  
  1979.     topOfPageFeatures(data);
  1980.     
  1981.     var srXmlNodes = data.getElementsByTagName('sr');
  1982.     for (var i = 0; i < srXmlNodes.length; i++) {
  1983.         var srXmlNode = srXmlNodes[i];
  1984.         var urlHash = getText(srXmlNode.getElementsByTagName('urlHash')[0]);
  1985.         var srNode = getSRByUrlHash(urlHash);
  1986.         if (srNode) {
  1987.             var recs = getText(srXmlNode.getElementsByTagName('recsHtml')[0]);
  1988.             updateRecsInUI(urlHash, recs, false, false);
  1989.         }
  1990.     }
  1991.  
  1992.     var moreResultsHtml = getText(data.getElementsByTagName('moreResults')[0]);
  1993.     var originalInsertPoint = getElementsByTagAndAttribute("div", "scOriginalInsertPoint", "1")[0];
  1994.     if (moreResultsHtml && originalInsertPoint) {
  1995.         originalInsertPoint.innerHTML = moreResultsHtml;
  1996.         originalInsertPoint.id = '';
  1997.         updateWOT();
  1998.     }
  1999.  
  2000.     if (!scIsFF) {
  2001.         focusOnNode("scFocus");
  2002.     }
  2003. }
  2004.  
  2005. function updateWOT(node) {
  2006.     if (scIsFF) {
  2007.         updateWebOfTrust(scGetDocument());
  2008.     }
  2009. }
  2010.  
  2011. function refreshDynamicContent() {
  2012.     if (scRefreshingDynamicContent || scRecsWereReset || getAllDisabled()) {
  2013.         return;
  2014.     }
  2015.  
  2016.     scRefreshingDynamicContent = true;
  2017.     ajax({    method: 'GET',
  2018.         url: scSecureHost + 'search/refresh?ssMapKey=' + getSSMapKey() + '&instId=' + scInstId + '&extensionVersion=' + scExtensionVersion,
  2019.         onload: function(xhr) {
  2020.             try {
  2021.                 var text = getResponseText(xhr);
  2022.                 if (text && !isServerError(text)) {
  2023.                     var xmlRoot = xmlParser(text);
  2024.                     var data = xmlRoot.getElementsByTagName('data')[0];
  2025.                     if (data) {
  2026.                         node = data.getElementsByTagName('notEnoughResults')[0];
  2027.                         if ((getText(node) != '1') || justDoingCraigslistImages()) {
  2028.                             updateUIAfterRefresh(data);
  2029.                         }
  2030.                     }
  2031.                 } else {
  2032.                     log('error in refresh', true);
  2033.                     undoUIChanges('refresh1');
  2034.                 }
  2035.  
  2036.                 if (typeof scGetSnippetsToUpload == 'function') {
  2037.                     scGetSnippetsToUpload(scGetDocument().body.innerHTML);
  2038.                 }
  2039.             } catch (e) {
  2040.                 log('error in refresh: ' + e.message, true);
  2041.             } finally {
  2042.                 scRefreshingDynamicContent = false;
  2043.             }
  2044.         },
  2045.         onerror: function() {
  2046.             scRefreshingDynamicContent = false;
  2047.             log('error in refresh', true);
  2048.             undoUIChanges('refresh2');
  2049.         }
  2050.     });
  2051. }
  2052.  
  2053. function topOfPageFeatures(data) {
  2054.     if (typeof scInvokePartnerHandlers == 'function') {
  2055.         scInvokePartnerHandlers(data);
  2056.     }
  2057.     
  2058.     if (typeof scAddNewsHeadlines == 'function') {
  2059.         var node = data.getElementsByTagName('addNewsHeadlines')[0];
  2060.         if (getText(node) == '1') {
  2061.             scAddNewsHeadlines();
  2062.         }
  2063.     }
  2064. }
  2065.  
  2066. function pageshowHandler() {
  2067.     refreshDynamicContent();
  2068. }
  2069.  
  2070. function isAdSectionDiv(node, id) {
  2071.     return (id && (id == scAdSectionDivName));
  2072. }
  2073.  
  2074. function getNavbar1() {
  2075.     return (typeof scNavbarDivName != 'undefined') ? scGetDocument().getElementById(scNavbarDivName) : null;
  2076. }
  2077.  
  2078. function getNavbar2() {
  2079.     return (typeof scNavbarDivName != 'undefined') ? scGetDocument().getElementById(scNavbarDiv2Name) : null;
  2080. }
  2081.  
  2082. function customizePageKeyHandler(event) {
  2083.     if (event.keyCode == 116) {
  2084.         event.keyCode = 0;
  2085.         event.returnValue = false;
  2086.         updateCustomizePage();
  2087.     }
  2088. }
  2089.  
  2090. function customizePageClickHandler(event) {
  2091.     try {
  2092.         var node = scIsIE ? event.srcElement : event.target;
  2093.         var id = node.getAttribute('id');
  2094.         if (startsWith(id, 'save')) {
  2095.             saveCustomizePage();
  2096.         } else {
  2097.             switch (id) {
  2098.                 case 'disableOdometer':
  2099.                     setOdometerDisabled(true);
  2100.                     updateCustomizePage();
  2101.                     break;
  2102.                 case 'enableOdometer':
  2103.                     setOdometerDisabled(false);
  2104.                     updateCustomizePage();
  2105.                     break;
  2106.                 case 'resetOdometer':
  2107.                     clearNumSearches();
  2108.                     clearNumResultsClicked();
  2109.                     clearNumResultsClickedWhenRecsAvailable();
  2110.                     clearNumRecsClicked();
  2111.                     updateCustomizePage();
  2112.                     break;
  2113.             }
  2114.         }
  2115.     } catch (e) {
  2116.     }
  2117. }
  2118.  
  2119. function updateCustomizePage() {
  2120.     try {
  2121.         var checkboxes = getElementsByTagAndAttribute("input", "type", "checkbox");
  2122.         for (var i = 0; i < checkboxes.length; i++) {
  2123.             checkboxes[i].checked = false;
  2124.         }
  2125.  
  2126.  
  2127.         scGetDocument().getElementById('enableAll').checked = !getAllDisabled();
  2128.  
  2129.         scGetDocument().getElementById('enableGoogle').checked = getAffectGoogle();
  2130.         scGetDocument().getElementById('enableYahoo').checked = getAffectYahoo();
  2131.         scGetDocument().getElementById('enableMSN').checked = getAffectBing();
  2132.         scGetDocument().getElementById('enableCraigslist').checked = getAffectCraigslist();
  2133.         scGetDocument().getElementById('enableLexis').checked = getAffectLexis();
  2134.  
  2135.         scGetDocument().getElementById('showBullseyes').checked = getShowBullseyes();
  2136.         scGetDocument().getElementById('showRecsOnSRClick').checked = getShowRecsOnSRClick();
  2137.         scGetDocument().getElementById('maxRecs').value = getMaxNumRecsForSRSelection();
  2138.         scGetDocument().getElementById('addCLImagePreviews').checked = getAddCLImagePreviews();
  2139.         scGetDocument().getElementById('addTopOfPageRefinements').checked = !getTopOfPageRefinementsDisabled();
  2140.         if (scIsFF) {
  2141.             scGetDocument().getElementById('displayIconInStatusBar').checked = !getStatusBarIconDisabled();
  2142.             scGetDocument().getElementById('displaySharingIconInUrlBar').checked = !getUrlBarIconDisabled();
  2143.         }
  2144.  
  2145.         scGetDocument().getElementById('odometerNumSearches').innerHTML = getNumSearches();
  2146.         scGetDocument().getElementById('odometerNumResultsClicked').innerHTML = getNumResultsClicked();
  2147.         scGetDocument().getElementById('odometerNumResultsClickedWhenRecsAvailable').innerHTML = getNumResultsClickedWhenRecsAvailable();
  2148.         scGetDocument().getElementById('odometerNumRecsClicked').innerHTML = getNumRecsClicked();
  2149.         scGetDocument().getElementById('odometerSearchBoost').innerHTML = getSearchBoost();
  2150.  
  2151.         if (getOdometerDisabled()) {
  2152.             scGetDocument().getElementById('disableOdometer').style.display = 'none';
  2153.             scGetDocument().getElementById('enableOdometer').style.display = 'block';
  2154.         } else {
  2155.             scGetDocument().getElementById('disableOdometer').style.display = 'block';
  2156.             scGetDocument().getElementById('enableOdometer').style.display = 'none';
  2157.         }
  2158.  
  2159.         var checkedDomains = getCheckedDomains();
  2160.         if (checkedDomains) {
  2161.             var domains = checkedDomains.split(',');
  2162.             if (domains && domains.length > 0) {
  2163.                 for (var i = 0; i < domains.length; i++) {
  2164.                     var domain = domains[i].toUpperCase();
  2165.                     var checkbox = scGetDocument().getElementById(domain);
  2166.                     if (checkbox) {
  2167.                         checkbox.checked = true;
  2168.                     }
  2169.                 }
  2170.             }
  2171.         }
  2172.  
  2173.         var preferredDomains = getPreferredDomains();
  2174.         if (preferredDomains) {
  2175.             var domains = preferredDomains.split(',');
  2176.             if (domains && domains.length > 0) {
  2177.                 for (var i = 0; i < domains.length; i++) {
  2178.                     var input = scGetDocument().getElementById('prefer' + i);
  2179.                     if (input) {
  2180.                         input.value = domains[i];
  2181.                     }
  2182.                 }
  2183.             }
  2184.         }
  2185.  
  2186.         var dislikedDomains = getDislikedDomains();
  2187.         if (dislikedDomains) {
  2188.             var domains = dislikedDomains.split(',');
  2189.             if (domains && domains.length > 0) {
  2190.                 for (var i = 0; i < domains.length; i++) {
  2191.                     var input = scGetDocument().getElementById('dislike' + i);
  2192.                     if (input) {
  2193.                         input.value = domains[i];
  2194.                     }
  2195.                 }
  2196.             }
  2197.         }
  2198.     } catch (e) {
  2199.     }
  2200. }
  2201.  
  2202. function saveCustomizePage() {
  2203.     setAllDisabled(!scGetDocument().getElementById('enableAll').checked);
  2204.  
  2205.     setAffectGoogle(scGetDocument().getElementById('enableGoogle').checked);
  2206.     setAffectYahoo(scGetDocument().getElementById('enableYahoo').checked);
  2207.     setAffectBing(scGetDocument().getElementById('enableMSN').checked);
  2208.     setAffectCraigslist(scGetDocument().getElementById('enableCraigslist').checked);
  2209.     setAffectLexis(scGetDocument().getElementById('enableLexis').checked);
  2210.  
  2211.     setShowBullseyes(scGetDocument().getElementById('showBullseyes').checked);
  2212.     setShowRecsOnSRClick(scGetDocument().getElementById('showRecsOnSRClick').checked);
  2213.     setMaxNumRecsForSRSelection(scGetDocument().getElementById('maxRecs').value);
  2214.     setAddCLImagePreviews(scGetDocument().getElementById('addCLImagePreviews').checked);
  2215.     setTopOfPageRefinementsDisabled(!scGetDocument().getElementById('addTopOfPageRefinements').checked);
  2216.     if (scIsFF) {
  2217.         setStatusBarIconDisabled(!scGetDocument().getElementById('displayIconInStatusBar').checked);
  2218.         setUrlBarIconDisabled(!scGetDocument().getElementById('displaySharingIconInUrlBar').checked);
  2219.     }
  2220.  
  2221.     var facebookWasInitiallyOn = contains(getCheckedDomains(), 'FACEBOOK');
  2222.  
  2223.     var domains = [];
  2224.     var checkboxes = getElementsByTagAndAttribute("input", "type", "checkbox");
  2225.     for (var i = 0; i < checkboxes.length; i++) {
  2226.         var checkbox = checkboxes[i];
  2227.         if (checkbox.checked && (checkbox.getAttribute(classWord()) == 'partner')) {
  2228.             var domain = checkbox.id;
  2229.             domains.push(domain);
  2230.         }
  2231.     }
  2232.     setCheckedDomains(domains.join(','));
  2233.  
  2234.     domains = [];
  2235.     for (var i = 0; i < 9; i++) {
  2236.         var domain = scGetDocument().getElementById('prefer' + i).value;
  2237.         if (domain) {
  2238.             domains.push(domain.replace(/,/g, '.'));
  2239.         }
  2240.     }
  2241.     setPreferredDomains(domains.join(','));
  2242.  
  2243.     domains = [];
  2244.     for (var i = 0; i < 9; i++) {
  2245.         var domain = scGetDocument().getElementById('dislike' + i).value;
  2246.         if (domain) {
  2247.             domains.push(domain.replace(/,/g, '.'));
  2248.         }
  2249.     }
  2250.     setDislikedDomains(domains.join(','));
  2251.  
  2252.     alert('Your preferences have been saved.');
  2253.  
  2254.     var facebookWasTurnedOn = !facebookWasInitiallyOn && contains(getCheckedDomains(), 'FACEBOOK');
  2255.     if (facebookWasTurnedOn) {
  2256.         window.open(scHost + '/facebookLogin.jsp');
  2257.     }
  2258. }
  2259.  
  2260. function executeHourlyCode() {
  2261.     if (getAllDisabled()) {
  2262.         return;
  2263.     }
  2264.  
  2265.     var timestamp = 0;
  2266.     try {
  2267.         timestamp = getHourlyCodeTimestamp();
  2268.     } catch (e) {
  2269.     }
  2270.  
  2271.     var oneHour = 1000 * 60 * 60;
  2272.     var now = (new Date()).getTime();
  2273.     if ((now - timestamp > oneHour) || !getHourlyCode()) {
  2274.         ajax({    method: 'GET',
  2275.             url: scSecureHost + 'search/getHourlyCode',
  2276.             mimeType:'text/plain; charset=us-ascii',
  2277.             onload: function(xhr) {
  2278.                 var js = getResponseText(xhr);
  2279.                 if (!isServerError(js) && contains(js, 'function(')) {
  2280.                     setHourlyCode(js);
  2281.                     setHourlyCodeTimestamp((new Date()).getTime());
  2282.                     eval(js);
  2283.                 }
  2284.             }
  2285.         });
  2286.         ajax({    method: 'GET',
  2287.             url: scSecureHost + 'search/getHourlyCode?page=2',
  2288.             mimeType:'text/plain; charset=us-ascii',
  2289.             onload: function(xhr) {
  2290.                 var js = getResponseText(xhr);
  2291.                 if (!isServerError(js) && contains(js, 'function(')) {
  2292.                     setHourlyCode2(js);
  2293.                     eval(js);
  2294.                 }
  2295.             }
  2296.         });
  2297.     }
  2298. }
  2299.  
  2300. function exeFilenameToPartnerCode(exefilename) {
  2301.     var partnerCode = null;
  2302.  
  2303.     if (exefilename) {
  2304.         var regex = /_([a-z]+)/;
  2305.         var matches = regex.exec(exefilename);
  2306.         if (matches && (matches.length > 0)) {
  2307.             partnerCode = matches[1].toUpperCase();
  2308.         }
  2309.     }
  2310.  
  2311.     return partnerCode;
  2312. }
  2313.  
  2314. scExtractUrlFromSpanTag = function(spanTag) {
  2315.     var url = null;
  2316.  
  2317.      if (spanTag) {
  2318.         url = removeSimpleHtmlTags(spanTag.innerHTML, false);
  2319.  
  2320.         var endPos = url.indexOf(' - ');
  2321.         if (endPos > 0) {
  2322.             url = url.substring(0, endPos);
  2323.         }
  2324.     }
  2325.  
  2326.     return url;
  2327. };
  2328.  
  2329. scEnableGoogle = function() {
  2330.     var args = window.location.search;
  2331.     if (getAffectGoogle() && contains(scCurrentPageDomain, '.google.') && contains(scCurrentPageDomain, 'www') && ((window.location.pathname == '/') || (window.location.pathname == '/search')) && !contains(args, 'define%3A') && !contains(args, '&swm=2')) {
  2332.         var googleNonAjax = (window.name == "") && (window.frames.length == 0);
  2333.           var googleAjaxInnerFrame = (window.name != "");
  2334.         var googleAjaxOuterFrame = (window.frames.length > 0) && (window.name == "") && (/q=/.test(window.location.href));
  2335.  
  2336.         return (googleNonAjax || googleAjaxInnerFrame || googleAjaxOuterFrame);
  2337.     }
  2338.     return false;
  2339. };
  2340.  
  2341. scEnableYahoo = function() {
  2342.     return getAffectYahoo() && contains(scCurrentPageDomain, 'search.yahoo.com') && !contains(scCurrentPageDomain, 'video.search.') && !contains(scCurrentPageDomain, 'images.search.') && !contains(scCurrentPageDomain, 'news.search.');
  2343. };
  2344.  
  2345. scEnableBing = function() {
  2346.     return getAffectBing() && contains(scCurrentPageDomain, 'bing.com') && (window.location.pathname == '/search');
  2347. };
  2348.  
  2349. scEnableCraigslist = function() {
  2350.     return (getAffectCraigslist() || getAddCLImagePreviews()) && contains(scCurrentPageDomain, '.craigslist.') && contains(scGetDocument().body.innerHTML, 'bchead');
  2351. };
  2352.  
  2353. scEnableLexis = function() {
  2354.     return getAffectLexis() && contains(scCurrentPageDomain, 'lexisweb.com') && startsWith(window.location.pathname, '/Search.aspx');
  2355. };
  2356.  
  2357. function usingHttps() {
  2358.     return startsWith(scSecureHost, 'https');
  2359. }
  2360.  
  2361. function onSCSite() {
  2362.     return (contains(scCurrentPageDomain, '.surfcanyon.com') || (scCurrentPageDomain == 'localhost'));
  2363. }
  2364.  
  2365. function initNewInstallation() {
  2366.     scHost = 'http://www.surfcanyon.com/';
  2367.     scSecureHost = 'https://www.surfcanyon.com/';
  2368.     scExtensionVersion = '3.0.3';
  2369.     var versionNoDots = scExtensionVersion.replace(/\./g, '');
  2370.  
  2371.     if (scIsIE) {
  2372.         initIE();
  2373.     } else if (scIsSafariMac) {
  2374.         initSafariMac();
  2375.     }
  2376.  
  2377.     if (!scIsFF && scDisplayErrors) {
  2378.         window.onerror = function(err, file, line) {
  2379.             alert('Line ' + line + ' of ' + file + ': ' + err);
  2380.             return true;
  2381.         }
  2382.     }
  2383.  
  2384.     var isNewInstall = false;
  2385.     scInstId = null;
  2386.     try {
  2387.         scInstId = getInstId();
  2388.     } catch (e) {
  2389.     }
  2390.     if (!scInstId) {
  2391.         scInstId = bigRandom();
  2392.         setInstId(scInstId);
  2393.         isNewInstall = true;
  2394.     }
  2395.  
  2396.     scPartnerCode = null;
  2397.     try {
  2398.         scPartnerCode = getPartnerCode();
  2399.     } catch (e) {
  2400.     }
  2401.     if (!scPartnerCode) {
  2402.         if (scIsIE) {
  2403.             var exefilename = getCharPreferenceValue("exefilename");
  2404.             scPartnerCode = exeFilenameToPartnerCode(exefilename);
  2405.         } else {
  2406.             scPartnerCode = 'SC';
  2407.         }
  2408.         setPartnerCode(scPartnerCode);
  2409.  
  2410.         if (isPartner(scPartnerCode) && (scPartnerCode != 'BT')) {
  2411.             addToCheckedDomains(scPartnerCode);
  2412.         }
  2413.     }
  2414.  
  2415.     if (isNewInstall) {
  2416.         if (!scIsIE && !startsWith(scPartnerCode, 'BT')) {
  2417.             var installedUrl = scHost + 'installed.jsp';
  2418.             if (isPartner(scPartnerCode)) {
  2419.                 installedUrl = installedUrl + '?partner=' + scPartnerCode;
  2420.             }
  2421.             openNewTab(installedUrl);
  2422.         }
  2423.         setLastSeenSplash(versionNoDots);
  2424.     }
  2425.  
  2426.     if (!usingHttps() && isPartner(scPartnerCode)) {
  2427.         scHost = scHost.replace('www', scPartnerCode.toLowerCase());
  2428.         scSecureHost = scHost;
  2429.     }
  2430.  
  2431.     scInstTimestamp = null;
  2432.     try {
  2433.         scInstTimestamp = getInstTimestamp();
  2434.     } catch (e) {
  2435.     }
  2436.     if (!scInstTimestamp) {
  2437.         setInstTimestamp((new Date()).getTime());
  2438.     }
  2439.  
  2440.     if (!scIsIE) {
  2441.         var lastSeenSplash = null;
  2442.         try {
  2443.             lastSeenSplash = getLastSeenSplash();
  2444.         } catch (e) {
  2445.         }
  2446.         if (lastSeenSplash != versionNoDots) {
  2447.             var splashUrl = scHost + 'newInVersion' + versionNoDots + '.jsp';
  2448.             if (isPartner(scPartnerCode)) {
  2449.                 splashUrl = splashUrl + '?partner=' + scPartnerCode;
  2450.             }
  2451.             openNewTab(splashUrl);
  2452.             setLastSeenSplash(versionNoDots);
  2453.         }
  2454.     }
  2455.  
  2456.     if (scIsFF) {
  2457.         try {
  2458.             if (!getAddedToSearchBar()) {
  2459.                 setAddedToSearchBar(true);
  2460.  
  2461.                 var searchDomain = (scPartnerCode && isPartner(scPartnerCode)) ? scPartnerCode.toLowerCase() : 'search';
  2462.                 var subpartner = getSubPartnerCode();
  2463.                 addToSearchBar('Surf Canyon', scHost + "opensearchfirefox.xml?partner=" + scPartnerCode + (subpartner ? ('&subpartner=' + subpartner) : ''));
  2464.             }
  2465.         } catch (e) {
  2466.         }
  2467.     }
  2468. }
  2469.  
  2470. function setup() {
  2471.     initNewInstallation();
  2472.  
  2473.     try {
  2474.         eval(getHourlyCode());
  2475.     } catch (e) {
  2476.     }
  2477.  
  2478.     var iframeHref = '';
  2479.     try {
  2480.         iframeHref = parent.location.href;
  2481.     } catch (e) {
  2482.     }
  2483.  
  2484.     try {
  2485.         scCurrentPageDomain = window.location.host;
  2486.     } catch (e) {
  2487.     }
  2488.     if (typeof scCurrentPageDomain == 'undefined') {
  2489.         return;
  2490.     }
  2491.  
  2492.     if (iframeHref && !contains(iframeHref, scCurrentPageDomain) && !onSCSite()) {
  2493.         return;
  2494.     }
  2495.  
  2496.     scAdStatus = 0;
  2497.     try {
  2498.         scAdStatus = getAdStatus();
  2499.     } catch (e) {
  2500.     }
  2501.  
  2502.     scStartTime = (new Date()).getTime();
  2503.     scSearchEngine = null;
  2504.     scSearchString = null;
  2505.     scBufferedEvent = null;
  2506.     scUploadResults = false;
  2507.     scFirstBatchReceived = false;
  2508.     scContinuingSession = false;
  2509.     scGettingRecs = false;
  2510.     scGettingMoreResults = false;
  2511.     scGoingToPage = false;
  2512.     scRefreshingDynamicContent = false;
  2513.     scRecsWereReset = false;
  2514.     scNumUserActions = 0;
  2515.     scSRSelectionCount = 0;
  2516.     scBatchNum = 0;
  2517.     scNumBatchesLeftToUpload = 0;
  2518.     scPageHasRecs = false;
  2519.     scLastBullseyeClick = (new Date()).getTime();
  2520.  
  2521.     scCheckedDomains = null;
  2522.     scPreferredDomains = null;
  2523.     scDislikedDomains = null;
  2524.     try {
  2525.         scCheckedDomains = getCheckedDomains();
  2526.         scPreferredDomains = getPreferredDomains();
  2527.         scDislikedDomains = getDislikedDomains();
  2528.     } catch (e) {
  2529.     }
  2530.  
  2531.     if (typeof scEnableGoogle_hourly == 'function') {
  2532.         scEnableGoogle = scEnableGoogle_hourly;
  2533.     }
  2534.     if (typeof scEnableYahoo_hourly == 'function') {
  2535.         scEnableYahoo = scEnableYahoo_hourly;
  2536.     }
  2537.     if (typeof scEnableBing_hourly == 'function') {
  2538.         scEnableBing = scEnableBing_hourly;
  2539.     }
  2540.     if (typeof scEnableCraigslist_hourly == 'function') {
  2541.         scEnableCraigslist = scEnableCraigslist_hourly;
  2542.     }
  2543.     if (typeof scEnableLexis_hourly == 'function') {
  2544.         scEnableLexis = scEnableLexis_hourly;
  2545.     }
  2546.  
  2547.     if (onSCSite()) {
  2548.         var bodyTag = scGetDocument().body;
  2549.         if (bodyTag && (bodyTag.id == 'scCustomizePage')) {
  2550.             var loc = window.location.toString();
  2551.             if (isPartner(scPartnerCode) && !contains(loc, 'partner=')) {
  2552.                 var separator = (contains(loc, '?')) ? '&' : '?';
  2553.                 window.location = loc + separator + 'partner=' + scPartnerCode;
  2554.                 return;
  2555.             }
  2556.  
  2557.             if (scIsIE) {
  2558.                 scGetDocument().attachEvent('onmouseup', customizePageClickHandler);
  2559.                 scGetDocument().attachEvent('onkeydown', customizePageKeyHandler);
  2560.             } else {
  2561.                 scGetDocument().addEventListener('click', customizePageClickHandler, true);
  2562.             }
  2563.             updateCustomizePage();
  2564.         } else {
  2565.             var fbData = document.getElementById('fbData');
  2566.             if (fbData) {
  2567.                 var uid = fbData.getAttribute('uid');
  2568.                 var sessionKey = fbData.getAttribute('sessionKey');
  2569.                 if (uid && sessionKey) {
  2570.                     setFacebookUID(uid);
  2571.                     setFacebookSessionKey(sessionKey);
  2572.                 }
  2573.             }
  2574.         }
  2575.     } else if (scEnableGoogle()) {
  2576.         scSearchEngine = 'google';
  2577.         scNumResultsToken = ':NR=';
  2578.         if (typeof scGetSRNodes_google == 'function') {
  2579.             scGetSRNodes = scGetSRNodes_google;
  2580.         } else {
  2581.             scGetSRNodes = function() {
  2582.                 var nodes = [];
  2583.             
  2584.                 var tags = scGetDocument().getElementsByTagName('li');
  2585.                 for (i = 0; i < tags.length; i++) {
  2586.                     var tag = tags[i];
  2587.                     var cls = tag.getAttribute(classWord());
  2588.                     if (cls && ((cls == 'g') || startsWith(cls, 'g '))) {
  2589.                         // this div is a header for interstitial results
  2590.                         if (!contains(tag.innerHTML, '<div class="med')) {
  2591.                             nodes[nodes.length] = tag;
  2592.                         }
  2593.                     }
  2594.                 }
  2595.  
  2596.                 return nodes;
  2597.             };
  2598.         }
  2599.         if (typeof scExtractUrlFromSRNode_google == 'function') {
  2600.             scExtractUrlFromSRNode = scExtractUrlFromSRNode_google;
  2601.         } else {
  2602.             scExtractUrlFromSRNode = function(srNode) {
  2603.                 var urlTag = getChildren(srNode, "cite")[0];
  2604.                 var url = scExtractUrlFromSpanTag(urlTag);
  2605.                 if (endsWith(url, '...')) {
  2606.                     var aTag = getChildren(srNode, "a")[0];
  2607.                     if (aTag) {
  2608.                         var href = aTag.getAttribute('href');
  2609.                         if (href) {
  2610.                             url = unescape(href);
  2611.  
  2612.                             if (startsWith(url, 'url')) {
  2613.                                 var pos = url.indexOf('href');
  2614.                                 if (pos > -1) {
  2615.                                     url = url.substring(pos);
  2616.                                 }
  2617.                             }
  2618.  
  2619.                             if (startsWith(url, 'http://')) {
  2620.                                 url = url.substring(7);
  2621.                             } else if (startsWith(url, 'https://')) {
  2622.                                 url = url.substring(8);
  2623.                             }
  2624.                             url = url.replace(/.*:\/\//, '');
  2625.                         }
  2626.                     }
  2627.                 }
  2628.                 return url;
  2629.             };
  2630.         }
  2631.     } else if (scEnableYahoo()) {
  2632.         var ss = scGetDocument().getElementById("yschsp");
  2633.         if (ss) {
  2634.             scSearchEngine = 'yahoo';
  2635.             scSearchString = ss.value;
  2636.             scNumResultsToken = 'n=';
  2637.             if (typeof scGetSRNodes_yahoo == 'function') {
  2638.                 scGetSRNodes = scGetSRNodes_yahoo;
  2639.             } else {
  2640.                 scGetSRNodes = function() {
  2641.                     var div = scGetDocument().getElementById('web');
  2642.                     var ol = getChildren(div, "ol")[0];
  2643.                     return (ol && ol.hasChildNodes ? ol.childNodes : []);
  2644.                 };
  2645.             }
  2646.             if (typeof scExtractUrlFromSRNode_yahoo == 'function') {
  2647.                 scExtractUrlFromSRNode = scExtractUrlFromSRNode_yahoo;
  2648.             } else {
  2649.                 scExtractUrlFromSRNode = function(srNode) {
  2650.                     var spanTag = getChildrenByTagAndClass(srNode, "span", "url")[0];
  2651.                     return scExtractUrlFromSpanTag(spanTag);
  2652.                 };
  2653.             }
  2654.         }
  2655.     } else if (scEnableBing()) {
  2656.         var q = document.getElementById("sb_form_q");
  2657.         if (q) {
  2658.             scSearchEngine = 'bing';
  2659.             scSearchString = q.value;
  2660.             scNumResultsToken = '&NRSLT=';
  2661.             if (typeof scGetSRNodes_bing == 'function') {
  2662.                 scGetSRNodes = scGetSRNodes_bing;
  2663.             } else {
  2664.                 scGetSRNodes = function() {
  2665.                     var div = document.getElementById('results');
  2666.                     var ul = getChildren(div, "ul")[0];
  2667.                     return (ul && ul.hasChildNodes ? ul.childNodes : []);
  2668.                 };
  2669.             }
  2670.             if (typeof scExtractUrlFromSRNode_bing == 'function') {
  2671.                 scExtractUrlFromSRNode = scExtractUrlFromSRNode_bing;
  2672.             } else {
  2673.                 scExtractUrlFromSRNode = function(srNode) {
  2674.                     var url = null;
  2675.                     var aTag = getChildren(srNode, "a")[0];
  2676.                     if (aTag) {
  2677.                         url = removeProtocol(aTag.href);
  2678.                     }
  2679.                     return url;
  2680.                 };
  2681.             }
  2682.         }
  2683.     } else if (scEnableCraigslist()) {
  2684.         var q = scGetDocument().getElementById("query");
  2685.         if (q) {
  2686.             scSearchEngine = 'craigslist';
  2687.             scSearchString = q.value;
  2688.             scNumResultsToken = null;
  2689.             if (typeof scGetSRNodes_craigslist == 'function') {
  2690.                 scGetSRNodes = scGetSRNodes_craigslist;
  2691.             } else {
  2692.                 scGetSRNodes = function() {
  2693.                     scOrigPage = scGetDocument().body.innerHTML;
  2694.                     var nodes = scGetDocument().getElementsByTagName('p');
  2695.                     var numNodes = nodes.length;
  2696.                     if (numNodes > scNumCraigslistResultsPerPage) {
  2697.                         var origNodes = nodes;
  2698.                         nodes = [];
  2699.                         for (var i = 0; i < numNodes; i++) {
  2700.                             var node = origNodes[i];
  2701.                             if (i < scNumCraigslistResultsPerPage) {
  2702.                                 nodes[i] = node;
  2703.                             } else if (getAffectCraigslist() && !getAllDisabled()) {
  2704.                                 var url = scExtractUrlFromSRNode_craigslist(node);
  2705.                                 if (!(contains(url, '/index') && endsWith(url, '00.html'))) {
  2706.                                     node.style.display = 'none';
  2707.                                 }
  2708.                             }
  2709.                         }
  2710.                     }
  2711.                     return nodes;
  2712.                 };
  2713.             }
  2714.             if (typeof scExtractUrlFromSRNode_craigslist == 'function') {
  2715.                 scExtractUrlFromSRNode = scExtractUrlFromSRNode_craigslist;
  2716.             } else {
  2717.                 scExtractUrlFromSRNode = function(srNode) {
  2718.                     var url = null;
  2719.                     var aTag = getChildren(srNode, "a")[0];
  2720.                     if (aTag) {
  2721.                         url = aTag.pathname;
  2722.                     }
  2723.                     return url;
  2724.                 };
  2725.             }
  2726.         }
  2727.     } else if (scEnableLexis()) {
  2728.         var q = scGetDocument().getElementById("Persist");
  2729.         if (q) {
  2730.             scSearchEngine = 'lexis';
  2731.             scSearchString = q.value;
  2732.             scNumResultsToken = null;
  2733.             if (typeof scGetSRNodes_lexis == 'function') {
  2734.                 scGetSRNodes = scGetSRNodes_lexis;
  2735.             } else {
  2736.                 scGetSRNodes = function() {
  2737.                     var div = scGetDocument().getElementById('searchResultsForSC');
  2738.                     return getChildren(div, "div");
  2739.                 };
  2740.             }
  2741.             if (typeof scExtractUrlFromSRNode_lexis == 'function') {
  2742.                 scExtractUrlFromSRNode = scExtractUrlFromSRNode_lexis;
  2743.             } else {
  2744.                 scExtractUrlFromSRNode = function(srNode) {
  2745.                     var url = null;
  2746.                     var aTag = getChildren(srNode, "a")[1];
  2747.                     if (aTag) {
  2748.                         url = aTag.title;
  2749.                     }
  2750.                     return url;
  2751.                 };
  2752.             }
  2753.  
  2754.             scAddLexisBullseyes = function() {
  2755.                 var alreadyHaveBullseyes = false;
  2756.                 var bullseyeIcon = scHost + 'search/images/bullseye.bmp';
  2757.                 for (var i = 0; i < scSRNodes.length; i++) {
  2758.                     var srNode = scSRNodes[i];
  2759.                     var url = scExtractUrlFromSRNode(srNode);
  2760.                     var attrVal = srNode.getAttribute('scUrlHash');
  2761.                     if (attrVal) {
  2762.                         alreadyHaveBullseyes = true;
  2763.                     }
  2764.                     if (url && !attrVal) {
  2765.                         var urlHash = getUrlHash(url);
  2766.                         srNode.setAttribute('scUrlHash', urlHash);
  2767.             
  2768.                         var span = scGetDocument().createElement('span');
  2769.                         span.setAttribute('id', 'scRecs' + urlHash);
  2770.                         srNode.appendChild(span);
  2771.             
  2772.                         var titleTag = getChildren(srNode, "br")[0];
  2773.                         if (titleTag && getShowBullseyes() && (getChildrenByTagAndClass(titleTag.parentNode, 'img', 'scBullseye').length == 0)) {
  2774.                             var imgTag = scGetDocument().createElement('img');
  2775.                             imgTag.setAttribute('border', '0');
  2776.                             imgTag.setAttribute(classWord(), 'scBullseye');
  2777.                             imgTag.setAttribute('src', bullseyeIcon);
  2778.                             imgTag.style.cursor = "pointer";
  2779.             
  2780.                             if (titleTag.tagName == 'BR') {
  2781.                                 titleTag.parentNode.insertBefore(imgTag, titleTag);
  2782.                             }
  2783.                         }
  2784.             
  2785.                         scLexisSearchResultListContainer = srNode.parentNode;
  2786.                     }
  2787.                 }
  2788.  
  2789.                 return alreadyHaveBullseyes;
  2790.             };
  2791.         }
  2792.     }
  2793.  
  2794.     if (!scSearchEngine) {
  2795.         executeHourlyCode();
  2796.         return;
  2797.     }
  2798.  
  2799.     waitForSerpAjaxToComplete();
  2800. }
  2801.  
  2802. scGetSearchStringFromGoogleSerp = function() {
  2803.     var aTags = scGetDocument().getElementsByTagName('a');
  2804.     for (i = 0; (i < aTags.length) && !scSearchString; i++) {
  2805.         var aTag = aTags[i];
  2806.         var href = aTag.href;
  2807.         if (contains(href, '.google.') && (contains(href, '/advanced_search?q=') || contains(href, '/swr?q='))) {
  2808.             scSearchString = href.replace(/.*\?q=/, '').replace(/&.*/, '');
  2809.         }
  2810.     }
  2811. };
  2812.  
  2813. function waitForSerpAjaxToComplete() {
  2814.     if (!scSearchString && (scSearchEngine == 'google')) {
  2815.         if (typeof scGetSearchStringFromGoogleSerp_hourly == 'function') {
  2816.             scGetSearchStringFromGoogleSerp = scGetSearchStringFromGoogleSerp_hourly;
  2817.         }
  2818.         scGetSearchStringFromGoogleSerp();
  2819.  
  2820.         if (!scSearchString) {
  2821.             setTimeout(waitForSerpAjaxToComplete, 200);
  2822.             return;
  2823.         }
  2824.     }
  2825.  
  2826.     if (scSearchString) {
  2827.         scSearchString = decodeEntities(scSearchString);
  2828.     } else if (scSearchEngine != 'craigslist') {
  2829.         return;
  2830.     }
  2831.  
  2832.     scSRNodes = scGetSRNodes();
  2833.     if (!scSRNodes || (scSRNodes.length == 0)) {
  2834.         return;
  2835.     }
  2836.  
  2837.     if ((typeof scAddLexisBullseyes == 'function') && !getAllDisabled()) {
  2838.         try {
  2839.             var alreadyHaveBullseyes = scAddLexisBullseyes();
  2840.             if (alreadyHaveBullseyes) {
  2841.                 return;
  2842.             }
  2843.         } catch (e) {
  2844.         }
  2845.     }
  2846.  
  2847.     if (scIsFF) {
  2848.         window.addEventListener('pageshow', pageshowHandler, false);
  2849.     }
  2850.  
  2851.     if (!getTopOfPageRefinementsDisabled() && !scGetDocument().getElementById('scTopOfPageRefinementLinks') && ((scSearchEngine == 'google' && getAffectGoogle()) || (scSearchEngine == 'yahoo' && getAffectYahoo()) || (scSearchEngine == 'bing' && getAffectBing()))) {
  2852.         try {
  2853.             var tagToLookFor = (scSearchEngine == 'bing') ? 'UL' : 'OL';
  2854.             var node = scSRNodes[0];
  2855.             while (node && node.parentNode) {
  2856.                 if (node.tagName == tagToLookFor) {
  2857.                     var div = scGetDocument().createElement("div");
  2858.                     div.innerHTML = '<div id=scTopOfPageRefinementLinks scTopPos=1 style="height: 20px; margin-top: 7px; margin-bottom: 7px;"></div>';
  2859.                     node.parentNode.insertBefore(div, node);
  2860.                     break;
  2861.                 }
  2862.                 node = node.parentNode;
  2863.             }
  2864.         } catch (e) {
  2865.         }
  2866.     }
  2867.  
  2868.     callExtensionInit();
  2869. }
  2870.  
  2871. function callExtensionInit() {
  2872.     var dislikedDomains = (scDislikedDomains != null) ? scDislikedDomains.split(',') : [];
  2873.  
  2874.     var srURLs = '';
  2875.     for (var i = 0; i < scSRNodes.length; i++) {
  2876.         var srNode = scSRNodes[i];
  2877.         var url = scExtractUrlFromSRNode(srNode);
  2878.         if (url) {
  2879.             if (scSearchEngine != 'craigslist') {
  2880.                 for (var j = 0; j < dislikedDomains.length; j++) {
  2881.                     var urlDomain = getDomainName(url);
  2882.                     var dislikedDomain = dislikedDomains[j];
  2883.                     if (equalsOrIsSubdomainOf(urlDomain, dislikedDomain) && !contains(scSearchString, dislikedDomain)) {
  2884.                         srNode.style.display = 'none';
  2885.                         break;
  2886.                     }
  2887.                 }
  2888.             }
  2889.  
  2890.             var urlHash = getUrlHash(url);
  2891.             if (srURLs == '') {
  2892.                 srURLs = urlHash;
  2893.             } else {
  2894.                 srURLs = srURLs + ',' + urlHash;
  2895.             }
  2896.         }
  2897.     }
  2898.  
  2899.     var browserLang = navigator.language ? navigator.language : navigator.userLanguage;
  2900.  
  2901.     ajax({    method: 'POST',
  2902.         url: scSecureHost + 'search/extensionInit',
  2903.         headers: {'Content-type': 'application/x-www-form-urlencoded'},
  2904.         data:    'ssMapKey=' + getSSMapKey() +
  2905.             '&serpUrl=' + encodeURIComponent(getSerpUrl()) +
  2906.             '&instId=' + scInstId +
  2907.             '&partner=' + scPartnerCode +
  2908.             '&instTimestamp=' + scInstTimestamp +
  2909.             '&adStatus=' + scAdStatus +
  2910.             '&extensionVersion=' + scExtensionVersion +
  2911.             '&searchString=' + encodeURIComponent(scSearchString) +
  2912.             '&searchEngine=' + scSearchEngine +
  2913.             '&isCustomSearch=' + (isCustomSearch(window.location.pathname) ? 1 : 0) +
  2914.             '&searchEngineDomain=' + scCurrentPageDomain +
  2915.             '&lang=' + getLang(scCurrentPageDomain) +
  2916.             '&browserLang=' + browserLang +
  2917.             '&localeCode=' + getLocaleCode() +
  2918.             '&numResultsPerPage=' + getNumResultsPerPage() +
  2919.             '&nativeSerpSearchResultUrls=' + srURLs +
  2920.             '&showBullseyes=' + (getShowBullseyes() ? 1 : 0) +
  2921.             '&showImagePreviews=' + (getAddImagePreviews() ? 1 : 0) +
  2922.             (scCheckedDomains ? ('&checkedDomains=' + scCheckedDomains) : '') +
  2923.             (scPreferredDomains ? ('&preferredDomains=' + scPreferredDomains) : '') +
  2924.             (scDislikedDomains ? ('&dislikedDomains=' + scDislikedDomains) : ''),
  2925.         onload: function(xhr) {
  2926.             var text = getResponseText(xhr);
  2927.             if (text && !isServerError(text)) {
  2928.                 var xmlRoot = xmlParser(text);
  2929.                 var data = xmlRoot.getElementsByTagName('data')[0];
  2930.                 if (data) {
  2931.                     var userStatusNode = data.getElementsByTagName('userStatus')[0];
  2932.                     scUserStatus = userStatusNode ? getText(userStatusNode) : "";
  2933.  
  2934.                     if (scUserStatus != '0') {
  2935.                         var sessionStatusNode = data.getElementsByTagName('sessionStatus')[0];
  2936.                         var javascriptNode = data.getElementsByTagName('javascript')[0];
  2937.                         if (sessionStatusNode && javascriptNode) {
  2938.                             var numUserActionsNode = data.getElementsByTagName('numUserActions')[0];
  2939.                             scNumUserActions = getText(numUserActionsNode) == '1';
  2940.                             var uploadResultsNode = data.getElementsByTagName('uploadResults')[0];
  2941.                             scUploadResults = getText(uploadResultsNode) == '1';
  2942.                             var hostnameNode = data.getElementsByTagName('hostname')[0];
  2943.                             var hostname = getText(hostnameNode);
  2944.  
  2945.                             if (usingHttps() && endsWith(hostname, '.surfcanyon.com')) {
  2946.                                 scHost = 'http://' + hostname + '/';
  2947.                             }
  2948.  
  2949.                             var js = getText(javascriptNode);
  2950.                             eval(js);
  2951.  
  2952.                             if (!getAllDisabled()) {
  2953.                                 var node = data.getElementsByTagName('notEnoughResults')[0];
  2954.                                 if ((getText(node) != '1') || justDoingCraigslistImages()) {
  2955.                                     initUI();
  2956.                                 } else if (scSearchEngine == 'lexis') {
  2957.                                     undoUIChanges('extensionInit');
  2958.                                 }
  2959.  
  2960.                                 var sessionStatus = getText(sessionStatusNode);
  2961.                                 if (sessionStatus == '1') {
  2962.                                     // log('creating new session', false);
  2963.                                     topOfPageFeatures(data);
  2964.                                     if (scUploadResults) {
  2965.                                         scNumBatchesLeftToUpload = scNumSRsForInitialUpload / scBatchSize;
  2966.                                         scBatchNum = 1;
  2967.                                         uploadSRs();
  2968.                                     }
  2969.                                     incNumSearches();
  2970.                                 } else {
  2971.                                     // log('re-using old session', false);
  2972.                                     scContinuingSession = true;
  2973.                                 }
  2974.  
  2975.                                 if (scContinuingSession) {
  2976.                                     refreshDynamicContent();
  2977.                                 }
  2978.                             }
  2979.                         }
  2980.                     }
  2981.                 }
  2982.             }
  2983.         }
  2984.     });
  2985. }
  2986.  
  2987. if (scIsIE && !isLexisWeb()) {
  2988.     window.attachEvent('onload', setup);
  2989. } else {
  2990.     setup();
  2991. }
  2992.  
  2993.